1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
8 declare void @use.i1(i1)
9 declare void @llvm.assume(i1)
12 define void @test_iv_wraps_1(i8 %len.n, i8 %a) {
13 ; CHECK-LABEL: @test_iv_wraps_1(
14 ; CHECK-NEXT: loop.ph:
15 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
17 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ -1, [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
18 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], 1
19 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
21 ; CHECK-NEXT: [[T_1:%.*]] = icmp uge i8 [[IV]], -1
22 ; CHECK-NEXT: call void @use.i1(i1 [[T_1]])
23 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
24 ; CHECK-NEXT: br label [[LOOP_HEADER]]
26 ; CHECK-NEXT: ret void
32 %iv = phi i8 [ 255, %loop.ph ], [ %iv.next, %loop.latch ]
33 %c = icmp eq i8 %iv, 1
34 br i1 %c, label %exit, label %loop.latch
37 %t.1 = icmp uge i8 %iv, 255
38 call void @use.i1(i1 %t.1)
39 %iv.next = add i8 %iv, 1
46 define void @test_iv_nuw_nsw_1_uge_start(i8 %len.n, i8 %a) {
47 ; CHECK-LABEL: @test_iv_nuw_nsw_1_uge_start(
48 ; CHECK-NEXT: loop.ph:
49 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
51 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ -1, [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
52 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], 1
53 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
55 ; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
56 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
58 ; CHECK-NEXT: call void @use.i1(i1 true)
59 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
60 ; CHECK-NEXT: br label [[LOOP_HEADER]]
62 ; CHECK-NEXT: ret void
68 %iv = phi i8 [ 255, %loop.ph ], [ %iv.next, %loop.latch ]
69 %c = icmp eq i8 %iv, 1
70 br i1 %c, label %exit, label %for.body
73 %c.2 = call i1 @cond()
74 br i1 %c.2, label %loop.latch, label %exit
77 %t.1 = icmp uge i8 %iv, 255
78 call void @use.i1(i1 %t.1)
79 %iv.next = add nsw nuw i8 %iv, 1
86 define void @test_iv_nuw_nsw_2_uge_start(i8 %len.n, i8 %a) {
87 ; CHECK-LABEL: @test_iv_nuw_nsw_2_uge_start(
88 ; CHECK-NEXT: loop.ph:
89 ; CHECK-NEXT: [[START:%.*]] = add i8 -2, 1
90 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
92 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
93 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], 1
94 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
96 ; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
97 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
99 ; CHECK-NEXT: call void @use.i1(i1 true)
100 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
101 ; CHECK-NEXT: br label [[LOOP_HEADER]]
103 ; CHECK-NEXT: ret void
106 %start = add i8 254, 1
107 br label %loop.header
110 %iv = phi i8 [ %start, %loop.ph ], [ %iv.next, %loop.latch ]
111 %c = icmp eq i8 %iv, 1
112 br i1 %c, label %exit, label %for.body
115 %c.2 = call i1 @cond()
116 br i1 %c.2, label %loop.latch, label %exit
119 %t.1 = icmp uge i8 %iv, 255
120 call void @use.i1(i1 %t.1)
121 %iv.next = add nsw nuw i8 %iv, 1
122 br label %loop.header
128 define void @test_iv_nsw_nuw_1_ult_end(i8 %len.n, i8 %a) {
129 ; CHECK-LABEL: @test_iv_nsw_nuw_1_ult_end(
130 ; CHECK-NEXT: loop.ph:
131 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
132 ; CHECK: loop.header:
133 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ -2, [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
134 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], 1
135 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
137 ; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
138 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
140 ; CHECK-NEXT: call void @use.i1(i1 false)
141 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
142 ; CHECK-NEXT: br label [[LOOP_HEADER]]
144 ; CHECK-NEXT: ret void
147 br label %loop.header
150 %iv = phi i8 [ 254, %loop.ph ], [ %iv.next, %loop.latch ]
151 %c = icmp eq i8 %iv, 1
152 br i1 %c, label %exit, label %for.body
155 %c.2 = call i1 @cond()
156 br i1 %c.2, label %loop.latch, label %exit
159 %t.1 = icmp ult i8 %iv, 1
160 call void @use.i1(i1 %t.1)
161 %iv.next = add nsw nuw i8 %iv, 1
162 br label %loop.header
169 define void @test_iv_nsw_nuw_2_ult_end(i8 %len.n, i8 %a, i8 %b) {
170 ; CHECK-LABEL: @test_iv_nsw_nuw_2_ult_end(
171 ; CHECK-NEXT: loop.ph:
172 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
173 ; CHECK: loop.header:
174 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[A:%.*]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
175 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], [[B:%.*]]
176 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
178 ; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
179 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
181 ; CHECK-NEXT: [[T_1:%.*]] = icmp ult i8 [[IV]], [[B]]
182 ; CHECK-NEXT: call void @use.i1(i1 [[T_1]])
183 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
184 ; CHECK-NEXT: br label [[LOOP_HEADER]]
186 ; CHECK-NEXT: ret void
189 br label %loop.header
192 %iv = phi i8 [ %a, %loop.ph ], [ %iv.next, %loop.latch ]
193 %c = icmp eq i8 %iv, %b
194 br i1 %c, label %exit, label %for.body
197 %c.2 = call i1 @cond()
198 br i1 %c.2, label %loop.latch, label %exit
201 %t.1 = icmp ult i8 %iv, %b
202 call void @use.i1(i1 %t.1)
203 %iv.next = add nsw nuw i8 %iv, 1
204 br label %loop.header
210 define void @test_iv_nsw_nuw_3_ult_start_var(i8 %len.n, i8 %a, i8 %b) {
211 ; CHECK-LABEL: @test_iv_nsw_nuw_3_ult_start_var(
212 ; CHECK-NEXT: loop.ph:
213 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
214 ; CHECK: loop.header:
215 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[A:%.*]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
216 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], [[B:%.*]]
217 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
219 ; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
220 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
222 ; CHECK-NEXT: call void @use.i1(i1 false)
223 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
224 ; CHECK-NEXT: br label [[LOOP_HEADER]]
226 ; CHECK-NEXT: ret void
229 br label %loop.header
232 %iv = phi i8 [ %a, %loop.ph ], [ %iv.next, %loop.latch ]
233 %c = icmp eq i8 %iv, %b
234 br i1 %c, label %exit, label %for.body
237 %c.2 = call i1 @cond()
238 br i1 %c.2, label %loop.latch, label %exit
241 %t.1 = icmp ult i8 %iv, %a
242 call void @use.i1(i1 %t.1)
243 %iv.next = add nsw nuw i8 %iv, 1
244 br label %loop.header
250 define void @test_iv_nsw_nuw_inc_2_ult_start_var(i8 %len.n, i8 %a, i8 %b) {
251 ; CHECK-LABEL: @test_iv_nsw_nuw_inc_2_ult_start_var(
252 ; CHECK-NEXT: loop.ph:
253 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
254 ; CHECK: loop.header:
255 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[A:%.*]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
256 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], [[B:%.*]]
257 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
259 ; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
260 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
262 ; CHECK-NEXT: call void @use.i1(i1 false)
263 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 2
264 ; CHECK-NEXT: br label [[LOOP_HEADER]]
266 ; CHECK-NEXT: ret void
269 br label %loop.header
272 %iv = phi i8 [ %a, %loop.ph ], [ %iv.next, %loop.latch ]
273 %c = icmp eq i8 %iv, %b
274 br i1 %c, label %exit, label %for.body
277 %c.2 = call i1 @cond()
278 br i1 %c.2, label %loop.latch, label %exit
281 %t.1 = icmp ult i8 %iv, %a
282 call void @use.i1(i1 %t.1)
283 %iv.next = add nsw nuw i8 %iv, 2
284 br label %loop.header