[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Analysis / ScalarEvolution / guards.ll
blobdd86cc65ddc148aeadb063d70e54023cf220d0ee
1 ; RUN: opt -S -indvars < %s | FileCheck %s
3 ; Check that SCEV is able to recognize and use guards to prove
4 ; conditions gaurding loop entries and backedges.  This isn't intended
5 ; to be a comprehensive test of SCEV's simplification capabilities,
6 ; tests directly testing e.g. if SCEV can elide a sext should go
7 ; elsewhere.
9 target datalayout = "n8:16:32:64"
11 declare void @llvm.experimental.guard(i1, ...)
13 declare void @use(i64 %x)
15 define void @test_1(i1* %cond_buf, i32* %len_buf) {
16 ; CHECK-LABEL: @test_1(
17 entry:
18   %len = load i32, i32* %len_buf, !range !{i32 1, i32 2147483648}
19   br label %loop
21 loop:
22 ; CHECK: loop:
23 ; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
24 ; CHECK:  %iv.inc.cmp = icmp ult i32 %iv.inc, %len
25 ; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
26 ; CHECK: leave:
28   %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
29   %iv.inc = add i32 %iv, 1
31   %iv.cmp = icmp slt i32 %iv, %len
32   call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ]
34   %iv.inc.cmp = icmp slt i32 %iv.inc, %len
35   call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
37   %becond = load volatile i1, i1* %cond_buf
38   br i1 %becond, label %loop, label %leave
40 leave:
41   ret void
44 define void @test_2(i32 %n, i32* %len_buf) {
45 ; CHECK-LABEL: @test_2(
46 ; CHECK:  [[LEN_ZEXT:%[^ ]+]] = zext i32 %len to i64
47 ; CHECK:  br label %loop
49 entry:
50   %len = load i32, i32* %len_buf, !range !{i32 0, i32 2147483648}
51   br label %loop
53 loop:
54 ; CHECK: loop:
55 ; CHECK:  %indvars.iv = phi i64 [ %indvars.iv.next, %loop ], [ 0, %entry ]
56 ; CHECK:  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
57 ; CHECK:  %iv.inc.cmp = icmp ult i64 %indvars.iv.next, [[LEN_ZEXT]]
58 ; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
59 ; CHECK: leave:
61   %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
62   %iv.inc = add i32 %iv, 1
64   %iv.sext = sext i32 %iv to i64
65   call void @use(i64 %iv.sext)
67   %iv.inc.cmp = icmp slt i32 %iv.inc, %len
68   call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
70   %becond = icmp ne i32 %iv, %n
71   br i1 %becond, label %loop, label %leave
73 leave:
74   ret void
77 define void @test_3(i1* %cond_buf, i32* %len_buf) {
78 ; CHECK-LABEL: @test_3(
80 entry:
81   %len = load i32, i32* %len_buf
82   %entry.cond = icmp sgt i32 %len, 0
83   call void(i1, ...) @llvm.experimental.guard(i1 %entry.cond) [ "deopt"() ]
84   br label %loop
86 loop:
87 ; CHECK: loop:
88 ; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
89 ; CHECK:  %iv.inc.cmp = icmp slt i32 %iv.inc, %len
90 ; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
91 ; CHECK: leave:
92   %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
93   %iv.inc = add i32 %iv, 1
95   %iv.cmp = icmp slt i32 %iv, %len
96   call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ]
98   %iv.inc.cmp = icmp slt i32 %iv.inc, %len
99   call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
101   %becond = load volatile i1, i1* %cond_buf
102   br i1 %becond, label %loop, label %leave
104 leave:
105   ret void
108 define void @test_4(i1* %cond_buf, i32* %len_buf) {
109 ; CHECK-LABEL: @test_4(
111 entry:
112   %len = load i32, i32* %len_buf
113   %entry.cond = icmp sgt i32 %len, 0
114   call void(i1, ...) @llvm.experimental.guard(i1 %entry.cond) [ "deopt"() ]
115   br label %loop
117 loop:
118   %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
119   %iv.inc = add i32 %iv, 1
121   %cond = load volatile i1, i1* %cond_buf
122   br i1 %cond, label %left, label %be
124 left:
125   ; Does not dominate the backedge, so cannot be used in the inductive proof
126   %iv.inc.cmp = icmp slt i32 %iv.inc, %len
127   call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
128   br label %be
131 ; CHECK: be:
132 ; CHECK-NEXT:  %iv.cmp = icmp slt i32 %iv, %len
133 ; CHECK-NEXT:  call void (i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ]
134 ; CHECK: leave:
136   %iv.cmp = icmp slt i32 %iv, %len
137   call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ]
139   %becond = load volatile i1, i1* %cond_buf
140   br i1 %becond, label %loop, label %leave
142 leave:
143   ret void