llvm.org GIT mirror llvm / f9de76f
[IndVars] Canonicalize comparisons between non-negative values and indvars -If there is a IndVar which is known to be non-negative, and there is a value which is also non-negative, then signed and unsigned comparisons between them produce the same result. Both of those can be seen in the same loop. To allow other optimizations to simplify them, we turn all instructions like %c = icmp slt i32 %iv, %b to %c = icmp ult i32 %iv, %b if both %iv and %b are known to be non-negative. Differential Revision: https://reviews.llvm.org/D34979 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307126 91177308-0d34-0410-b5e6-96231b3b80d8 Max Kazantsev 2 years ago
5 changed file(s) with 62 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
261261 ICmp->setPredicate(InvariantPredicate);
262262 ICmp->setOperand(0, NewLHS);
263263 ICmp->setOperand(1, NewRHS);
264 } else if (ICmpInst::isSigned(Pred) &&
265 SE->isKnownNonNegative(S) && SE->isKnownNonNegative(X)) {
266 DEBUG(dbgs() << "INDVARS: Turn to unsigned comparison: " << *ICmp << '\n');
267 ICmp->setPredicate(ICmpInst::getUnsignedPredicate(Pred));
264268 } else
265269 return;
266270
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 }
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