blob: dd86cc65ddc148aeadb063d70e54023cf220d0ee [file] [log] [blame]
Sanjoy Das2512d0c2016-05-10 00:31:49 +00001; RUN: opt -S -indvars < %s | FileCheck %s
2
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.
8
9target datalayout = "n8:16:32:64"
10
11declare void @llvm.experimental.guard(i1, ...)
12
Max Kazantsev0ed79622018-06-13 02:25:32 +000013declare void @use(i64 %x)
14
Sanjoy Das2512d0c2016-05-10 00:31:49 +000015define void @test_1(i1* %cond_buf, i32* %len_buf) {
16; CHECK-LABEL: @test_1(
17entry:
18 %len = load i32, i32* %len_buf, !range !{i32 1, i32 2147483648}
19 br label %loop
20
21loop:
22; CHECK: loop:
23; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
Max Kazantsevb9edcbc2017-07-08 17:17:30 +000024; CHECK: %iv.inc.cmp = icmp ult i32 %iv.inc, %len
Sanjoy Das2512d0c2016-05-10 00:31:49 +000025; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
26; CHECK: leave:
27
28 %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
29 %iv.inc = add i32 %iv, 1
30
31 %iv.cmp = icmp slt i32 %iv, %len
32 call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ]
33
34 %iv.inc.cmp = icmp slt i32 %iv.inc, %len
35 call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
36
37 %becond = load volatile i1, i1* %cond_buf
38 br i1 %becond, label %loop, label %leave
39
40leave:
41 ret void
42}
43
44define void @test_2(i32 %n, i32* %len_buf) {
45; CHECK-LABEL: @test_2(
Max Kazantsevb9edcbc2017-07-08 17:17:30 +000046; CHECK: [[LEN_ZEXT:%[^ ]+]] = zext i32 %len to i64
Sanjoy Das2512d0c2016-05-10 00:31:49 +000047; CHECK: br label %loop
48
49entry:
50 %len = load i32, i32* %len_buf, !range !{i32 0, i32 2147483648}
51 br label %loop
52
53loop:
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
Max Kazantsevb9edcbc2017-07-08 17:17:30 +000057; CHECK: %iv.inc.cmp = icmp ult i64 %indvars.iv.next, [[LEN_ZEXT]]
Sanjoy Das2512d0c2016-05-10 00:31:49 +000058; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
59; CHECK: leave:
60
61 %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
62 %iv.inc = add i32 %iv, 1
63
64 %iv.sext = sext i32 %iv to i64
Max Kazantsev0ed79622018-06-13 02:25:32 +000065 call void @use(i64 %iv.sext)
Sanjoy Das2512d0c2016-05-10 00:31:49 +000066
67 %iv.inc.cmp = icmp slt i32 %iv.inc, %len
68 call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
69
70 %becond = icmp ne i32 %iv, %n
71 br i1 %becond, label %loop, label %leave
72
73leave:
74 ret void
75}
76
77define void @test_3(i1* %cond_buf, i32* %len_buf) {
78; CHECK-LABEL: @test_3(
79
80entry:
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
85
86loop:
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
94
95 %iv.cmp = icmp slt i32 %iv, %len
96 call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ]
97
98 %iv.inc.cmp = icmp slt i32 %iv.inc, %len
99 call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
100
101 %becond = load volatile i1, i1* %cond_buf
102 br i1 %becond, label %loop, label %leave
103
104leave:
105 ret void
106}
107
108define void @test_4(i1* %cond_buf, i32* %len_buf) {
109; CHECK-LABEL: @test_4(
110
111entry:
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
116
117loop:
118 %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
119 %iv.inc = add i32 %iv, 1
120
121 %cond = load volatile i1, i1* %cond_buf
122 br i1 %cond, label %left, label %be
123
124left:
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
129
130be:
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:
135
136 %iv.cmp = icmp slt i32 %iv, %len
137 call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ]
138
139 %becond = load volatile i1, i1* %cond_buf
140 br i1 %becond, label %loop, label %leave
141
142leave:
143 ret void
144}