llvm.org GIT mirror llvm / 0acdce1
Re-enable "[IndVars] Canonicalize comparisons between non-negative values and indvars" The patch was reverted due to a bug. The bug was that if the IV is the 2nd operand of the icmp instruction, then the "Pred" variable gets swapped and differs from the instruction's predicate. In this patch we use the original predicate to do the transformation. Also added a test case that exercises this situation. Differentian Revision: https://reviews.llvm.org/D35107 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307477 91177308-0d34-0410-b5e6-96231b3b80d8 Max Kazantsev 2 years ago
5 changed file(s) with 115 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
155155 void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp, Value *IVOperand) {
156156 unsigned IVOperIdx = 0;
157157 ICmpInst::Predicate Pred = ICmp->getPredicate();
158 ICmpInst::Predicate OriginalPred = Pred;
158159 if (IVOperand != ICmp->getOperand(0)) {
159160 // Swapped
160161 assert(IVOperand == ICmp->getOperand(1) && "Can't find IVOperand");
263264 ICmp->setPredicate(InvariantPredicate);
264265 ICmp->setOperand(0, NewLHS);
265266 ICmp->setOperand(1, NewRHS);
267 } else if (ICmpInst::isSigned(OriginalPred) &&
268 SE->isKnownNonNegative(S) && SE->isKnownNonNegative(X)) {
269 // If we were unable to make anything above, all we can is to canonicalize
270 // the comparison hoping that it will open the doors for other
271 // optimizations. If we find out that we compare two non-negative values,
272 // we turn the instruction's predicate to its unsigned version. Note that
273 // we cannot rely on Pred here unless we check if we have swapped it.
274 assert(ICmp->getPredicate() == OriginalPred && "Predicate changed?");
275 DEBUG(dbgs() << "INDVARS: Turn to unsigned comparison: " << *ICmp << '\n');
276 ICmp->setPredicate(ICmpInst::getUnsignedPredicate(OriginalPred));
266277 } else
267278 return;
268279
1818 loop:
1919 ; CHECK: loop:
2020 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
21 ; CHECK: %iv.inc.cmp = icmp slt i32 %iv.inc, %len
21 ; CHECK: %iv.inc.cmp = icmp ult i32 %iv.inc, %len
2222 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
2323 ; CHECK: leave:
2424
4040
4141 define void @test_2(i32 %n, i32* %len_buf) {
4242 ; CHECK-LABEL: @test_2(
43 ; CHECK: [[LEN_SEXT:%[^ ]+]] = sext i32 %len to i64
43 ; CHECK: [[LEN_ZEXT:%[^ ]+]] = zext i32 %len to i64
4444 ; CHECK: br label %loop
4545
4646 entry:
5151 ; CHECK: loop:
5252 ; CHECK: %indvars.iv = phi i64 [ %indvars.iv.next, %loop ], [ 0, %entry ]
5353 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
54 ; CHECK: %iv.inc.cmp = icmp slt i64 %indvars.iv.next, [[LEN_SEXT]]
54 ; CHECK: %iv.inc.cmp = icmp ult i64 %indvars.iv.next, [[LEN_ZEXT]]
5555 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
5656 ; CHECK: leave:
5757
0 ; RUN: opt -S -indvars < %s | FileCheck %s
1
2 ; Check that we replace signed comparisons between non-negative values with
3 ; unsigned comparisons if we can.
4
5 target datalayout = "n8:16:32:64"
6
7 define i32 @test_01(i32 %a, i32 %b, i32* %p) {
8
9 ; CHECK-LABEL: @test_01(
10 ; CHECK-NOT: icmp slt
11 ; CHECK: %cmp1 = icmp ult i32 %iv, 100
12 ; CHECK: %cmp2 = icmp ult i32 %iv, 100
13 ; CHECK-NOT: %cmp3
14 ; CHECK: %exitcond = icmp ne i32 %iv.next, 1000
15
16 entry:
17 br label %loop.entry
18
19 loop.entry:
20 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.be ]
21 %cmp1 = icmp slt i32 %iv, 100
22 br i1 %cmp1, label %b1, label %b2
23
24 b1:
25 store i32 %iv, i32* %p
26 br label %merge
27
28 b2:
29 store i32 %a, i32* %p
30 br label %merge
31
32 merge:
33 %cmp2 = icmp ult i32 %iv, 100
34 br i1 %cmp2, label %b3, label %b4
35
36 b3:
37 store i32 %iv, i32* %p
38 br label %loop.be
39
40 b4:
41 store i32 %b, i32* %p
42 br label %loop.be
43
44 loop.be:
45 %iv.next = add i32 %iv, 1
46 %cmp3 = icmp slt i32 %iv.next, 1000
47 br i1 %cmp3, label %loop.entry, label %exit
48
49 exit:
50 ret i32 %iv
51 }
52
53 define i32 @test_02(i32 %a, i32 %b, i32* %p) {
54
55 ; CHECK-LABEL: @test_02(
56 ; CHECK-NOT: icmp sgt
57 ; CHECK: %cmp1 = icmp ugt i32 100, %iv
58 ; CHECK: %cmp2 = icmp ugt i32 100, %iv
59 ; CHECK-NOT: %cmp3
60 ; CHECK: %exitcond = icmp ne i32 %iv.next, 1000
61
62 entry:
63 br label %loop.entry
64
65 loop.entry:
66 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.be ]
67 %cmp1 = icmp sgt i32 100, %iv
68 br i1 %cmp1, label %b1, label %b2
69
70 b1:
71 store i32 %iv, i32* %p
72 br label %merge
73
74 b2:
75 store i32 %a, i32* %p
76 br label %merge
77
78 merge:
79 %cmp2 = icmp ugt i32 100, %iv
80 br i1 %cmp2, label %b3, label %b4
81
82 b3:
83 store i32 %iv, i32* %p
84 br label %loop.be
85
86 b4:
87 store i32 %b, i32* %p
88 br label %loop.be
89
90 loop.be:
91 %iv.next = add i32 %iv, 1
92 %cmp3 = icmp sgt i32 1000, %iv.next
93 br i1 %cmp3, label %loop.entry, label %exit
94
95 exit:
96 ret i32 %iv
97 }
110110 ; Indvars should not turn the second loop into an infinite one.
111111
112112 ; CHECK-LABEL: @func_11(
113 ; CHECK: %tmp5 = icmp slt i32 %__key6.0, 10
113 ; CHECK: %tmp5 = icmp ult i32 %__key6.0, 10
114114 ; CHECK-NOT: br i1 true, label %noassert68, label %unrolledend
115115
116116 define i32 @func_11() nounwind uwtable {
162162
163163 ; In this case the second loop only has a single iteration, fold the header away
164164 ; CHECK-LABEL: @func_12(
165 ; CHECK: %tmp5 = icmp slt i32 %__key6.0, 10
165 ; CHECK: %tmp5 = icmp ult i32 %__key6.0, 10
166166 ; CHECK: br i1 true, label %noassert68, label %unrolledend
167167 define i32 @func_12() nounwind uwtable {
168168 entry:
6363 ; CHECK-LABEL: @test2
6464 ; CHECK: for.body4.us
6565 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
66 ; CHECK: %cmp2.us = icmp slt i64
66 ; CHECK: %cmp2.us = icmp ult i64
6767 ; CHECK-NOT: %2 = trunc i64 %indvars.iv.next to i32
6868 ; CHECK-NOT: %cmp2.us = icmp slt i32
6969