Skip to content

Commit d6f47ae

Browse files
committed
[SCEV] SCEVExpander::isHighCostExpansionHelper(): cost-model min/max (PR44668)
Summary: Previosly we simply always said that `SCEVMinMaxExpr` is too costly to expand. But this isn't really true, it expands into just a comparison+swap pair. And again much like with add/mul, there will be one less such pair than the number of operands. And we need to count the cost of operands themselves. This does change a number of testcases, and as far as i can tell, all of these changes are improvements, in the sense that we fixed up more latches to do the [in]equality comparison. This concludes cost-modelling changes, no other SCEV expressions exist as of now. This is a part of addressing [[ https://bugs.llvm.org/show_bug.cgi?id=44668 | PR44668 ]]. Reviewers: reames, mkazantsev, wmi, sanjoy Reviewed By: mkazantsev Subscribers: hiraditya, javed.absar, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D73744
1 parent 0f3c9b5 commit d6f47ae

File tree

11 files changed

+236
-121
lines changed

11 files changed

+236
-121
lines changed

llvm/lib/Analysis/ScalarEvolutionExpander.cpp

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,27 +2277,31 @@ bool SCEVExpander::isHighCostExpansionHelper(
22772277
return BudgetRemaining < 0;
22782278
}
22792279

2280-
if (S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr) {
2281-
const SCEVNAryExpr *NAry = dyn_cast<SCEVNAryExpr>(S);
2280+
if (const SCEVNAryExpr *NAry = dyn_cast<SCEVNAryExpr>(S)) {
2281+
Type *OpType = NAry->getType();
22822282

2283-
unsigned Opcode;
2283+
int PairCost;
22842284
switch (S->getSCEVType()) {
22852285
case scAddExpr:
2286-
Opcode = Instruction::Add;
2286+
PairCost = TTI.getOperationCost(Instruction::Add, OpType);
22872287
break;
22882288
case scMulExpr:
2289-
Opcode = Instruction::Mul;
2289+
// TODO: this is a very pessimistic cost modelling for Mul,
2290+
// because of Bin Pow algorithm actually used by the expander,
2291+
// see SCEVExpander::visitMulExpr(), ExpandOpBinPowN().
2292+
PairCost = TTI.getOperationCost(Instruction::Mul, OpType);
2293+
break;
2294+
case scSMaxExpr:
2295+
case scUMaxExpr:
2296+
case scSMinExpr:
2297+
case scUMinExpr:
2298+
PairCost = TTI.getOperationCost(Instruction::ICmp, OpType) +
2299+
TTI.getOperationCost(Instruction::Select, OpType);
22902300
break;
22912301
default:
22922302
llvm_unreachable("There are no other variants here.");
22932303
}
22942304

2295-
Type *OpType = NAry->getType();
2296-
int PairCost = TTI.getOperationCost(Opcode, OpType);
2297-
// TODO: this is a very pessimistic cost modelling for Mul,
2298-
// because of Bin Pow algorithm actually used by the expander,
2299-
// see SCEVExpander::visitMulExpr(), ExpandOpBinPowN().
2300-
23012305
assert(NAry->getNumOperands() > 1 &&
23022306
"Nary expr should have more than 1 operand.");
23032307
for (const SCEV *Op : NAry->operands()) {
@@ -2311,14 +2315,7 @@ bool SCEVExpander::isHighCostExpansionHelper(
23112315
return BudgetRemaining < 0;
23122316
}
23132317

2314-
// HowManyLessThans uses a Max expression whenever the loop is not guarded by
2315-
// the exit condition.
2316-
if (isa<SCEVMinMaxExpr>(S))
2317-
return true;
2318-
2319-
// If we haven't recognized an expensive SCEV pattern, assume it's an
2320-
// expression produced by program code.
2321-
return false;
2318+
llvm_unreachable("No other scev expressions possible.");
23222319
}
23232320

23242321
Value *SCEVExpander::expandCodeForPredicate(const SCEVPredicate *Pred,

llvm/test/Transforms/IndVarSimplify/elim-extend.ll

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
88
define void @postincConstIV(i8* %base, i32 %limit) nounwind {
99
; CHECK-LABEL: @postincConstIV(
1010
; CHECK-NEXT: entry:
11-
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[LIMIT:%.*]] to i64
11+
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[LIMIT:%.*]], 0
12+
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[LIMIT]], i32 0
13+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[SMAX]], 1
14+
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP1]] to i64
1215
; CHECK-NEXT: br label [[LOOP:%.*]]
1316
; CHECK: loop:
1417
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
@@ -19,8 +22,8 @@ define void @postincConstIV(i8* %base, i32 %limit) nounwind {
1922
; CHECK-NEXT: store i8 0, i8* [[POSTADR]]
2023
; CHECK-NEXT: [[POSTADRNSW:%.*]] = getelementptr inbounds i8, i8* [[BASE]], i64 [[INDVARS_IV_NEXT]]
2124
; CHECK-NEXT: store i8 0, i8* [[POSTADRNSW]]
22-
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[TMP0]], [[INDVARS_IV]]
23-
; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
25+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
26+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
2427
; CHECK: exit:
2528
; CHECK-NEXT: br label [[RETURN:%.*]]
2629
; CHECK: return:
@@ -113,7 +116,9 @@ define void @nestedIV(i8* %address, i32 %limit) nounwind {
113116
; CHECK-NEXT: entry:
114117
; CHECK-NEXT: [[LIMITDEC:%.*]] = add i32 [[LIMIT:%.*]], -1
115118
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[LIMITDEC]] to i64
116-
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT]] to i64
119+
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[LIMIT]], 1
120+
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP1]], i32 [[LIMIT]], i32 1
121+
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
117122
; CHECK-NEXT: br label [[OUTERLOOP:%.*]]
118123
; CHECK: outerloop:
119124
; CHECK-NEXT: [[INDVARS_IV1:%.*]] = phi i64 [ [[INDVARS_IV_NEXT2:%.*]], [[OUTERMERGE:%.*]] ], [ 0, [[ENTRY:%.*]] ]
@@ -149,8 +154,8 @@ define void @nestedIV(i8* %address, i32 %limit) nounwind {
149154
; CHECK-NEXT: [[ADR5:%.*]] = getelementptr i8, i8* [[ADDRESS]], i64 [[OFS5]]
150155
; CHECK-NEXT: store i8 0, i8* [[ADR5]]
151156
; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nuw nsw i64 [[INDVARS_IV1]], 1
152-
; CHECK-NEXT: [[TMP47:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT2]], [[TMP1]]
153-
; CHECK-NEXT: br i1 [[TMP47]], label [[OUTERLOOP]], label [[RETURN:%.*]]
157+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT2]], [[WIDE_TRIP_COUNT]]
158+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[OUTERLOOP]], label [[RETURN:%.*]]
154159
; CHECK: return:
155160
; CHECK-NEXT: ret void
156161
;

llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -529,16 +529,19 @@ define void @func_17(i32* %len.ptr) {
529529
; CHECK-NEXT: [[ENTRY_COND:%.*]] = and i1 [[ENTRY_COND_0]], [[ENTRY_COND_1]]
530530
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
531531
; CHECK: loop.preheader:
532+
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[LEN]], 0
533+
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[LEN]], i32 0
534+
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[SMAX]], -5
532535
; CHECK-NEXT: br label [[LOOP:%.*]]
533536
; CHECK: loop:
534-
; CHECK-NEXT: [[IV_2:%.*]] = phi i32 [ [[IV_2_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
537+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ -6, [[LOOP_PREHEADER]] ]
535538
; CHECK-NEXT: call void @side_effect()
536-
; CHECK-NEXT: [[IV_2_INC]] = add nuw i32 [[IV_2]], 1
539+
; CHECK-NEXT: [[IV_INC]] = add nsw i32 [[IV]], 1
537540
; CHECK-NEXT: br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
538541
; CHECK: be:
539542
; CHECK-NEXT: call void @side_effect()
540-
; CHECK-NEXT: [[BE_COND:%.*]] = icmp slt i32 [[IV_2]], [[LEN]]
541-
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
543+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[TMP1]]
544+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
542545
; CHECK: leave.loopexit:
543546
; CHECK-NEXT: br label [[LEAVE]]
544547
; CHECK: leave:
@@ -685,6 +688,8 @@ define void @func_20(i32* %length.ptr) {
685688
; CHECK-NEXT: [[LENGTH_IS_NONZERO:%.*]] = icmp ne i32 [[LENGTH]], 0
686689
; CHECK-NEXT: br i1 [[LENGTH_IS_NONZERO]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
687690
; CHECK: loop.preheader:
691+
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[LENGTH]], 1
692+
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[LENGTH]], i32 1
688693
; CHECK-NEXT: br label [[LOOP:%.*]]
689694
; CHECK: loop:
690695
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
@@ -693,8 +698,8 @@ define void @func_20(i32* %length.ptr) {
693698
; CHECK-NEXT: br i1 [[EXITCOND]], label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
694699
; CHECK: be:
695700
; CHECK-NEXT: call void @side_effect()
696-
; CHECK-NEXT: [[BE_COND:%.*]] = icmp slt i32 [[IV_INC]], [[LENGTH]]
697-
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
701+
; CHECK-NEXT: [[EXITCOND1:%.*]] = icmp ne i32 [[IV_INC]], [[SMAX]]
702+
; CHECK-NEXT: br i1 [[EXITCOND1]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
698703
; CHECK: leave.loopexit:
699704
; CHECK-NEXT: br label [[LEAVE]]
700705
; CHECK: leave:

llvm/test/Transforms/IndVarSimplify/eliminate-trunc.ll

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,16 @@ define void @test_01(i32 %n) {
3636
;
3737
; CHECK-LABEL: @test_01(
3838
; CHECK-NEXT: entry:
39-
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
39+
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[N:%.*]], 0
40+
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 0
41+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[SMAX]], 1
42+
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP1]] to i64
4043
; CHECK-NEXT: br label [[LOOP:%.*]]
4144
; CHECK: loop:
4245
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
4346
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
44-
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
45-
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
47+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
48+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
4649
; CHECK: exit:
4750
; CHECK-NEXT: ret void
4851
;
@@ -63,13 +66,16 @@ define void @test_02(i32 %n) {
6366
;
6467
; CHECK-LABEL: @test_02(
6568
; CHECK-NEXT: entry:
66-
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
69+
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[N:%.*]], 2147483646
70+
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 2147483646
71+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[SMAX]], 1
72+
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP1]] to i64
6773
; CHECK-NEXT: br label [[LOOP:%.*]]
6874
; CHECK: loop:
6975
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 2147483646, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
7076
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
71-
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
72-
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
77+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
78+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
7379
; CHECK: exit:
7480
; CHECK-NEXT: ret void
7581
;
@@ -113,13 +119,16 @@ define void @test_04(i32 %n) {
113119
;
114120
; CHECK-LABEL: @test_04(
115121
; CHECK-NEXT: entry:
116-
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
122+
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[N:%.*]], -2147483647
123+
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 -2147483647
124+
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[SMAX]], 1
117125
; CHECK-NEXT: br label [[LOOP:%.*]]
118126
; CHECK: loop:
119127
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483647, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
120128
; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1
121-
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
122-
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
129+
; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
130+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP1]]
131+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
123132
; CHECK: exit:
124133
; CHECK-NEXT: ret void
125134
;
@@ -243,13 +252,16 @@ exit:
243252
define void @test_02_unsigned(i32 %n) {
244253
; CHECK-LABEL: @test_02_unsigned(
245254
; CHECK-NEXT: entry:
246-
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
255+
; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], -2
256+
; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 -2
257+
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[UMAX]], 1
247258
; CHECK-NEXT: br label [[LOOP:%.*]]
248259
; CHECK: loop:
249260
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 4294967294, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
250261
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
251-
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
252-
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
262+
; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
263+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP1]]
264+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
253265
; CHECK: exit:
254266
; CHECK-NEXT: ret void
255267
;
@@ -318,13 +330,16 @@ exit:
318330
define void @test_05_unsigned(i32 %n) {
319331
; CHECK-LABEL: @test_05_unsigned(
320332
; CHECK-NEXT: entry:
321-
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
333+
; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1
334+
; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
335+
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[UMAX]], 1
322336
; CHECK-NEXT: br label [[LOOP:%.*]]
323337
; CHECK: loop:
324338
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
325339
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
326-
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
327-
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
340+
; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
341+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP1]]
342+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
328343
; CHECK: exit:
329344
; CHECK-NEXT: ret void
330345
;
@@ -366,14 +381,18 @@ exit:
366381
define void @test_07(i32* %p, i32 %n) {
367382
; CHECK-LABEL: @test_07(
368383
; CHECK-NEXT: entry:
384+
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[N:%.*]], 0
385+
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 0
386+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[SMAX]], 1
387+
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP1]] to i64
369388
; CHECK-NEXT: br label [[LOOP:%.*]]
370389
; CHECK: loop:
371390
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
372391
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
373392
; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
374393
; CHECK-NEXT: store i32 [[NARROW_IV]], i32* [[P:%.*]]
375-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]]
376-
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
394+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
395+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
377396
; CHECK: exit:
378397
; CHECK-NEXT: ret void
379398
;
@@ -451,15 +470,17 @@ exit:
451470
define void @test_10(i32 %n) {
452471
; CHECK-LABEL: @test_10(
453472
; CHECK-NEXT: entry:
454-
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
473+
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 100
474+
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
475+
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 90
476+
; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 90
477+
; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[UMIN]], -99
455478
; CHECK-NEXT: br label [[LOOP:%.*]]
456479
; CHECK: loop:
457480
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -100, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
458481
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
459-
; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], [[SEXT]]
460-
; CHECK-NEXT: [[NEGCMP:%.*]] = icmp slt i64 [[IV]], -10
461-
; CHECK-NEXT: [[CMP:%.*]] = and i1 [[TMP0]], [[NEGCMP]]
462-
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
482+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[TMP3]]
483+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
463484
; CHECK: exit:
464485
; CHECK-NEXT: ret void
465486
;
@@ -530,13 +551,15 @@ define void @test_12(i32* %p) {
530551
; CHECK-LABEL: @test_12(
531552
; CHECK-NEXT: entry:
532553
; CHECK-NEXT: [[N:%.*]] = load i32, i32* [[P:%.*]], !range !0
533-
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N]] to i64
554+
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[N]], 1
555+
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
556+
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
534557
; CHECK-NEXT: br label [[LOOP:%.*]]
535558
; CHECK: loop:
536559
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
537560
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
538-
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV_NEXT]], [[ZEXT]]
539-
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
561+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
562+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
540563
; CHECK: exit:
541564
; CHECK-NEXT: ret void
542565
;

llvm/test/Transforms/IndVarSimplify/full_widening.ll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
77
define i32 @test_01(double* %p, double %x, i32* %np, i32* %mp, i32 %k) {
88
; CHECK-LABEL: @test_01(
99
; CHECK-NEXT: entry:
10-
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[K:%.*]] to i64
10+
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[K:%.*]], 1
11+
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[K]], i32 1
12+
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
1113
; CHECK-NEXT: br label [[LOOP:%.*]]
1214
; CHECK: loop:
1315
; CHECK-NEXT: [[IV_WIDE:%.*]] = phi i64 [ [[CANONICAL_IV_NEXT_I:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
@@ -17,8 +19,8 @@ define i32 @test_01(double* %p, double %x, i32* %np, i32* %mp, i32 %k) {
1719
; CHECK-NEXT: [[MUL:%.*]] = fmul double [[X:%.*]], [[LOAD]]
1820
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds double, double* [[P]], i64 [[IV_WIDE]]
1921
; CHECK-NEXT: store atomic double [[MUL]], double* [[GEP2]] unordered, align 8
20-
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i64 [[CANONICAL_IV_NEXT_I]], [[TMP0]]
21-
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
22+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[CANONICAL_IV_NEXT_I]], [[WIDE_TRIP_COUNT]]
23+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
2224
; CHECK: exit:
2325
; CHECK-NEXT: ret i32 0
2426
;

llvm/test/Transforms/IndVarSimplify/iv-widen.ll

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,17 @@ define void @loop_1(i32 %lim) {
122122
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp ne i32 [[LIM:%.*]], 0
123123
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
124124
; CHECK: loop.preheader:
125-
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[LIM]] to i64
125+
; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[LIM]], 2
126+
; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[LIM]], i32 2
127+
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[UMAX]] to i64
126128
; CHECK-NEXT: br label [[LOOP:%.*]]
127129
; CHECK: loop:
128130
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 1, [[LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
129131
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
130132
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
131133
; CHECK-NEXT: call void @dummy.i64(i64 [[TMP1]])
132-
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT]], [[TMP0]]
133-
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[LEAVE_LOOPEXIT:%.*]]
134+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
135+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT:%.*]]
134136
; CHECK: leave.loopexit:
135137
; CHECK-NEXT: br label [[LEAVE]]
136138
; CHECK: leave:
@@ -165,7 +167,9 @@ define void @loop_2(i32 %size, i32 %nsteps, i32 %hsize, i32* %lined, i8 %tmp1) {
165167
; CHECK-NEXT: [[BC0:%.*]] = bitcast i32* [[LINED:%.*]] to i8*
166168
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[SIZE]] to i64
167169
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[HSIZE:%.*]] to i64
168-
; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[NSTEPS:%.*]] to i64
170+
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[NSTEPS:%.*]], 1
171+
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP2]], i32 [[NSTEPS]], i32 1
172+
; CHECK-NEXT: [[WIDE_TRIP_COUNT11:%.*]] = zext i32 [[SMAX]] to i64
169173
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
170174
; CHECK: for.body:
171175
; CHECK-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
@@ -200,8 +204,8 @@ define void @loop_2(i32 %size, i32 %nsteps, i32 %hsize, i32* %lined, i8 %tmp1) {
200204
; CHECK-NEXT: br label [[FOR_INC]]
201205
; CHECK: for.inc:
202206
; CHECK-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1
203-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT8]], [[TMP2]]
204-
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
207+
; CHECK-NEXT: [[EXITCOND12:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT8]], [[WIDE_TRIP_COUNT11]]
208+
; CHECK-NEXT: br i1 [[EXITCOND12]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
205209
; CHECK: for.end.loopexit:
206210
; CHECK-NEXT: ret void
207211
;

0 commit comments

Comments
 (0)