llvm.org GIT mirror llvm / d380dee
[SCEV] No-wrap flags are not propagated when folding "{S,+,X}+T ==> {S+T,+,X}" Summary: **Description** This makes `WidenIV::widenIVUse` (IndVarSimplify.cpp) fail to widen narrow IV uses in some cases. The latter affects IndVarSimplify which may not eliminate narrow IV's when there actually exists such a possibility, thereby producing ineffective code. When `WidenIV::widenIVUse` gets a NarrowUse such as `{(-2 + %inc.lcssa),+,1}<nsw><%for.body3>`, it first tries to get a wide recurrence for it via the `getWideRecurrence` call. `getWideRecurrence` returns recurrence like this: `{(sext i32 (-2 + %inc.lcssa) to i64),+,1}<nsw><%for.body3>`. Then a wide use operation is generated by `cloneIVUser`. The generated wide use is evaluated to `{(-2 + (sext i32 %inc.lcssa to i64))<nsw>,+,1}<nsw><%for.body3>`, which is different from the `getWideRecurrence` result. `cloneIVUser` sees the difference and returns nullptr. This patch also fixes the broken LLVM tests by adding missing <nsw> entries introduced by the correction. **Minimal reproducer:** ``` int foo(int a, int b, int c); int baz(); void bar() { int arr[20]; int i = 0; for (i = 0; i < 4; ++i) arr[i] = baz(); for (; i < 20; ++i) arr[i] = foo(arr[i - 4], arr[i - 3], arr[i - 2]); } ``` **Clang command line:** ``` clang++ -mllvm -debug -S -emit-llvm -O3 --target=aarch64-linux-elf test.cpp -o test.ir ``` **Expected result:** The ` -mllvm -debug` log shows that all the IV's for the second `for` loop have been eliminated. Reviewers: sanjoy Subscribers: atrick, asl, aemerson, mzolotukhin, llvm-commits Differential Revision: http://reviews.llvm.org/D20058 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270695 91177308-0d34-0410-b5e6-96231b3b80d8 Oleg Ranevskyy 4 years ago
7 changed file(s) with 45 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
23052305
23062306 SmallVector AddRecOps(AddRec->op_begin(),
23072307 AddRec->op_end());
2308 AddRecOps[0] = getAddExpr(LIOps);
2308 // This follows from the fact that the no-wrap flags on the outer add
2309 // expression are applicable on the 0th iteration, when the add recurrence
2310 // will be equal to its start value.
2311 AddRecOps[0] = getAddExpr(LIOps, Flags);
23092312
23102313 // Build the new addrec. Propagate the NUW and NSW flags if both the
23112314 // outer add and the inner addrec are guaranteed to have no overflow.
9595 ; CHECK-NEXT: Grouped accesses:
9696 ; CHECK-NEXT: Group {{.*}}[[ZERO]]:
9797 ; CHECK-NEXT: (Low: %c High: (78 + %c))
98 ; CHECK-NEXT: Member: {(2 + %c),+,4}
98 ; CHECK-NEXT: Member: {(2 + %c),+,4}
9999 ; CHECK-NEXT: Member: {%c,+,4}
100100 ; CHECK-NEXT: Group {{.*}}[[ONE]]:
101101 ; CHECK-NEXT: (Low: %a High: (40 + %a))
102 ; CHECK-NEXT: Member: {(2 + %a),+,2}
102 ; CHECK-NEXT: Member: {(2 + %a),+,2}
103103 ; CHECK-NEXT: Member: {%a,+,2}
104104 ; CHECK-NEXT: Group {{.*}}[[TWO]]:
105105 ; CHECK-NEXT: (Low: %b High: (38 + %b))
167167 ; CHECK-NEXT: Grouped accesses:
168168 ; CHECK-NEXT: Group {{.*}}[[ZERO]]:
169169 ; CHECK-NEXT: (Low: %c High: (78 + %c))
170 ; CHECK-NEXT: Member: {(2 + %c),+,4}
170 ; CHECK-NEXT: Member: {(2 + %c),+,4}
171171 ; CHECK-NEXT: Member: {%c,+,4}
172172 ; CHECK-NEXT: Group {{.*}}[[ONE]]:
173173 ; CHECK-NEXT: (Low: %a High: (40 + %a))
245245 ; CHECK-NEXT: %arrayidxA2 = getelementptr i16, i16* %a, i64 %ind2
246246 ; CHECK-NEXT: Grouped accesses:
247247 ; CHECK-NEXT: Group {{.*}}[[ZERO]]:
248 ; CHECK-NEXT: (Low: ((2 * %offset) + %a) High: (9998 + (2 * %offset) + %a))
249 ; CHECK-NEXT: Member: {((2 * %offset) + %a),+,2}<%for.body>
248 ; CHECK-NEXT: (Low: ((2 * %offset) + %a) High: (9998 + (2 * %offset) + %a))
249 ; CHECK-NEXT: Member: {((2 * %offset) + %a),+,2}<%for.body>
250250 ; CHECK-NEXT: Group {{.*}}[[ONE]]:
251251 ; CHECK-NEXT: (Low: %a High: (9998 + %a))
252252 ; CHECK-NEXT: Member: {%a,+,2}<%for.body>
1414 target triple = "aarch64--linux-gnueabi"
1515
1616 ; CHECK: function 'f':
17 ; CHECK: (Low: (20000 + %a) High: (60000 + %a))
17 ; CHECK: (Low: (20000 + %a) High: (60000 + %a))
1818
1919 @B = common global i32* null, align 8
2020 @A = common global i32* null, align 8
5757 ; Here it is not obvious what the limits are, since 'step' could be negative.
5858
5959 ; CHECK: Low: (-1 + (-1 * ((-60001 + (-1 * %a)) umax (-60001 + (40000 * %step) + (-1 * %a)))))
60 ; CHECK: High: ((60000 + %a) umax (60000 + (-40000 * %step) + %a))
60 ; CHECK: High: ((60000 + %a) umax (60000 + (-40000 * %step) + %a))
6161
6262 define void @g(i64 %step) {
6363 entry:
419419
420420 %j = add nsw i32 %i, 1
421421 ; CHECK: %index32 =
422 ; CHECK: --> {(1 + %offset),+,1}
422 ; CHECK: --> {(1 + %offset),+,1}
423423 %index32 = add nsw i32 %j, %offset
424424
425425 %ptr = getelementptr inbounds float, float* %input, i32 %index32
561561 %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]
562562
563563 ; CHECK: %index32 =
564 ; CHECK: --> {((-1 * %halfsub) + %start),+,1}
564 ; CHECK: --> {((-1 * %halfsub) + %start),+,1}
565565 %index32 = sub nsw i32 %i, %halfsub
566566 %index64 = sext i32 %index32 to i64
567567
620620
621621 %j = add nsw i32 %i, 1
622622 ; CHECK: %index32 =
623 ; CHECK: --> {(1 + (-1 * %offset)),+,1}
623 ; CHECK: --> {(1 + (-1 * %offset)),+,1}
624624 %index32 = sub nsw i32 %j, %offset
625625
626626 %ptr = getelementptr inbounds float, float* %input, i32 %index32
3838 %8 = sext i32 %7 to i64 ; [#uses=1]
3939
4040 ; CHECK: %9 = getelementptr inbounds double, double* %q, i64 %8
41 ; CHECK: {(8 + %q),+,16}<%bb>
41 ; CHECK: {(8 + %q),+,16}<%bb>
4242 %9 = getelementptr inbounds double, double* %q, i64 %8 ; [#uses=1]
4343
4444 ; Artificially repeat the above three instructions, this time using
5050 %t8 = sext i32 %t7 to i64 ; [#uses=1]
5151
5252 ; CHECK: %t9 = getelementptr inbounds double, double* %q, i64 %t8
53 ; CHECK: {(8 + %q),+,16}<%bb>
53 ; CHECK: {(8 + %q),+,16}<%bb>
5454 %t9 = getelementptr inbounds double, double* %q, i64 %t8 ; [#uses=1]
5555
5656 %10 = load double, double* %9, align 8 ; [#uses=1]
3636 %8 = sext i32 %7 to i64 ; [#uses=1]
3737
3838 ; CHECK: %9 = getelementptr inbounds double, double* %q, i64 %8
39 ; CHECK: {(8 + %q),+,16}<%bb>
39 ; CHECK: {(8 + %q),+,16}<%bb>
4040 %9 = getelementptr inbounds double, double* %q, i64 %8 ; [#uses=1]
4141
4242 ; Artificially repeat the above three instructions, this time using
4848 %t8 = sext i32 %t7 to i64 ; [#uses=1]
4949
5050 ; CHECK: %t9 = getelementptr inbounds double, double* %q, i64 %t8
51 ; CHECK: {(8 + %q),+,16}<%bb>
51 ; CHECK: {(8 + %q),+,16}<%bb>
5252 %t9 = getelementptr inbounds double, double* %q, i64 %t8 ; [#uses=1]
5353
5454 %10 = load double, double* %9, align 8 ; [#uses=1]
6565 store i32 0, i32* %__first.addr.02.i.i, align 4
6666 %ptrincdec.i.i = getelementptr inbounds i32, i32* %__first.addr.02.i.i, i64 1
6767 ; CHECK: %ptrincdec.i.i
68 ; CHECK-NEXT: --> {(4 + %begin),+,4}<%for.body.i.i>
68 ; CHECK-NEXT: --> {(4 + %begin),+,4}<%for.body.i.i>
6969 %cmp.i.i = icmp eq i32* %ptrincdec.i.i, %end
7070 br i1 %cmp.i.i, label %for.cond.for.end_crit_edge.i.i, label %for.body.i.i
7171
9191 ; CHECK: {1,+,1}<%for.body.i.i>
9292 %ptrincdec.i.i = getelementptr inbounds i32, i32* %begin, i64 %tmp
9393 ; CHECK: %ptrincdec.i.i =
94 ; CHECK: {(4 + %begin),+,4}<%for.body.i.i>
94 ; CHECK: {(4 + %begin),+,4}<%for.body.i.i>
9595 %__first.addr.08.i.i = getelementptr inbounds i32, i32* %begin, i64 %indvar.i.i
9696 ; CHECK: %__first.addr.08.i.i
9797 ; CHECK: {%begin,+,4}<%for.body.i.i>
123123 }
124124
125125 ; CHECK-LABEL: PR12375
126 ; CHECK: --> {(4 + %arg),+,4}<%bb1>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (8 + %arg)
126 ; CHECK: --> {(4 + %arg),+,4}<%bb1>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (8 + %arg)
127127 define i32 @PR12375(i32* readnone %arg) {
128128 bb:
129129 %tmp = getelementptr inbounds i32, i32* %arg, i64 2
142142 }
143143
144144 ; CHECK-LABEL: PR12376
145 ; CHECK: --> {(4 + %arg),+,4}<%bb2>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((3 + (-1 * %arg) + (%arg umax %arg1)) /u 4)) + %arg)
145 ; CHECK: --> {(4 + %arg),+,4}<%bb2>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((3 + (-1 * %arg) + (%arg umax %arg1)) /u 4)) + %arg)
146146 define void @PR12376(i32* nocapture %arg, i32* nocapture %arg1) {
147147 bb:
148148 br label %bb2
176176 for.end:
177177 ret void
178178 }
179
180 ; This test checks if no-wrap flags are propagated when folding {S,+,X}+T ==> {S+T,+,X}
181 ; CHECK-LABEL: test4
182 ; CHECK: %idxprom
183 ; CHECK-NEXT: --> {(-2 + (sext i32 %arg to i64)),+,1}<%for.body>
184 define void @test4(i32 %arg) {
185 entry:
186 %array = alloca [10 x i32], align 4
187 br label %for.body
188
189 for.body:
190 %index = phi i32 [ %inc5, %for.body ], [ %arg, %entry ]
191 %sub = add nsw i32 %index, -2
192 %idxprom = sext i32 %sub to i64
193 %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %array, i64 0, i64 %idxprom
194 %data = load i32, i32* %arrayidx, align 4
195 %inc5 = add nsw i32 %index, 1
196 %cmp2 = icmp slt i32 %inc5, 10
197 br i1 %cmp2, label %for.body, label %for.end
198
199 for.end:
200 ret void
201 }