[memprof] Move YAML support to MemProfYAML.h (NFC) (#119515)
[llvm-project.git] / llvm / test / Transforms / IndVarSimplify / outer_phi.ll
blob03303fb431326159849330f4a373d65f5cdd0426
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=indvars -S | FileCheck %s
4 declare i1 @cond()
5 declare i32 @llvm.smax.i32(i32, i32)
7 ; FIXME: In all tests in this file, signed_cond is equivalent to unsigned_cond, and therefore
8 ; one of the checks in the inner loop can be removed. The key to proving it is to prove that
9 ; %iv starts from something that is non-negative and only goes up. The positivity of its start
10 ; follows from the fact that %outer.iv also starts from somethign non-negative and only goes
11 ; up or remains same between iterations.
12 define i32 @test_01(i32 %a, i32 %b) {
13 ; CHECK-LABEL: @test_01(
14 ; CHECK-NEXT:  entry:
15 ; CHECK-NEXT:    [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0
16 ; CHECK-NEXT:    br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]]
17 ; CHECK:       outer.preheader:
18 ; CHECK-NEXT:    br label [[OUTER:%.*]]
19 ; CHECK:       outer:
20 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
21 ; CHECK-NEXT:    br label [[INNER:%.*]]
22 ; CHECK:       inner:
23 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
24 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
25 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
26 ; CHECK:       inner.1:
27 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
28 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
29 ; CHECK:       inner.backedge:
30 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
31 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
32 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
33 ; CHECK:       outer.backedge:
34 ; CHECK-NEXT:    [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
35 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
36 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
37 ; CHECK:       failure:
38 ; CHECK-NEXT:    unreachable
39 ; CHECK:       side.exit:
40 ; CHECK-NEXT:    ret i32 0
41 ; CHECK:       exit:
42 ; CHECK-NEXT:    ret i32 1
44 entry:
45   %b_is_non_negative = icmp sge i32 %b, 0
46   br i1 %b_is_non_negative, label %outer, label %failure
48 outer:
49   %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
50   br label %inner
53 inner:
54   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
55   %signed_cond = icmp slt i32 %iv, %b
56   br i1 %signed_cond, label %inner.1, label %side.exit
58 inner.1:
59   %unsigned_cond = icmp ult i32 %iv, %b
60   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
62 inner.backedge:
63   %iv.next = add nuw nsw i32 %iv, 1
64   %inner.loop.cond = call i1 @cond()
65   br i1 %inner.loop.cond, label %inner, label %outer.backedge
67 outer.backedge:
68   %outer.loop.cond = call i1 @cond()
69   br i1 %outer.loop.cond, label %outer, label %exit
71 failure:
72   unreachable
74 side.exit:
75   ret i32 0
77 exit:
78   ret i32 1
81 ; FIXME: iv <u b, b >=s 0 --> iv <s b. We should be able to remove the 2nd check.
82 define i32 @test_01a(i32 %a, i32 %b) {
83 ; CHECK-LABEL: @test_01a(
84 ; CHECK-NEXT:  entry:
85 ; CHECK-NEXT:    [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0
86 ; CHECK-NEXT:    br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]]
87 ; CHECK:       outer.preheader:
88 ; CHECK-NEXT:    br label [[OUTER:%.*]]
89 ; CHECK:       outer:
90 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
91 ; CHECK-NEXT:    br label [[INNER:%.*]]
92 ; CHECK:       inner:
93 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
94 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
95 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
96 ; CHECK:       inner.1:
97 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
98 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
99 ; CHECK:       inner.backedge:
100 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
101 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
102 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
103 ; CHECK:       outer.backedge:
104 ; CHECK-NEXT:    [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
105 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
106 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
107 ; CHECK:       failure:
108 ; CHECK-NEXT:    unreachable
109 ; CHECK:       side.exit:
110 ; CHECK-NEXT:    ret i32 0
111 ; CHECK:       exit:
112 ; CHECK-NEXT:    ret i32 1
114 entry:
115   %b_is_non_negative = icmp sge i32 %b, 0
116   br i1 %b_is_non_negative, label %outer, label %failure
118 outer:
119   %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
120   br label %inner
123 inner:
124   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
125   %signed_cond = icmp ult i32 %iv, %b
126   br i1 %signed_cond, label %inner.1, label %side.exit
128 inner.1:
129   %unsigned_cond = icmp slt i32 %iv, %b
130   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
132 inner.backedge:
133   %iv.next = add nuw nsw i32 %iv, 1
134   %inner.loop.cond = call i1 @cond()
135   br i1 %inner.loop.cond, label %inner, label %outer.backedge
137 outer.backedge:
138   %outer.loop.cond = call i1 @cond()
139   br i1 %outer.loop.cond, label %outer, label %exit
141 failure:
142   unreachable
144 side.exit:
145   ret i32 0
147 exit:
148   ret i32 1
151 define i32 @test_02(i32 %a, i32 %b) {
152 ; CHECK-LABEL: @test_02(
153 ; CHECK-NEXT:  entry:
154 ; CHECK-NEXT:    [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0
155 ; CHECK-NEXT:    br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]]
156 ; CHECK:       outer.preheader:
157 ; CHECK-NEXT:    br label [[OUTER:%.*]]
158 ; CHECK:       outer:
159 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
160 ; CHECK-NEXT:    br label [[INNER:%.*]]
161 ; CHECK:       inner:
162 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
163 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
164 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
165 ; CHECK:       inner.1:
166 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
167 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
168 ; CHECK:       inner.backedge:
169 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
170 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
171 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
172 ; CHECK:       outer.backedge:
173 ; CHECK-NEXT:    [[OUTER_MERGE]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
174 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
175 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
176 ; CHECK:       failure:
177 ; CHECK-NEXT:    unreachable
178 ; CHECK:       side.exit:
179 ; CHECK-NEXT:    ret i32 0
180 ; CHECK:       exit:
181 ; CHECK-NEXT:    ret i32 1
183 entry:
184   %b_is_non_negative = icmp sge i32 %b, 0
185   br i1 %b_is_non_negative, label %outer, label %failure
187 outer:
188   %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge]
189   br label %inner
192 inner:
193   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
194   %signed_cond = icmp slt i32 %iv, %b
195   br i1 %signed_cond, label %inner.1, label %side.exit
197 inner.1:
198   %unsigned_cond = icmp ult i32 %iv, %b
199   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
201 inner.backedge:
202   %iv.next = add nuw nsw i32 %iv, 1
203   %inner.loop.cond = call i1 @cond()
204   br i1 %inner.loop.cond, label %inner, label %outer.backedge
206 outer.backedge:
207   %outer.merge = phi i32 [%iv.next, %inner.backedge]
208   %outer.loop.cond = call i1 @cond()
209   br i1 %outer.loop.cond, label %outer, label %exit
211 failure:
212   unreachable
214 side.exit:
215   ret i32 0
217 exit:
218   ret i32 1
221 define i32 @test_03(i32 %a, i32 %b) {
222 ; CHECK-LABEL: @test_03(
223 ; CHECK-NEXT:  entry:
224 ; CHECK-NEXT:    [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0
225 ; CHECK-NEXT:    br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]]
226 ; CHECK:       outer.preheader:
227 ; CHECK-NEXT:    br label [[OUTER:%.*]]
228 ; CHECK:       outer:
229 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
230 ; CHECK-NEXT:    [[OUTER_COND_1:%.*]] = call i1 @cond()
231 ; CHECK-NEXT:    br i1 [[OUTER_COND_1]], label [[INNER_PREHEADER:%.*]], label [[NO_INNER:%.*]]
232 ; CHECK:       inner.preheader:
233 ; CHECK-NEXT:    br label [[INNER:%.*]]
234 ; CHECK:       no_inner:
235 ; CHECK-NEXT:    [[OUTER_COND_2:%.*]] = call i1 @cond()
236 ; CHECK-NEXT:    br label [[OUTER_BACKEDGE]]
237 ; CHECK:       inner:
238 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ], [ [[OUTER_IV]], [[INNER_PREHEADER]] ]
239 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
240 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
241 ; CHECK:       inner.1:
242 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
243 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
244 ; CHECK:       inner.backedge:
245 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
246 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
247 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE_LOOPEXIT:%.*]]
248 ; CHECK:       outer.backedge.loopexit:
249 ; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
250 ; CHECK-NEXT:    br label [[OUTER_BACKEDGE]]
251 ; CHECK:       outer.backedge:
252 ; CHECK-NEXT:    [[OUTER_MERGE]] = phi i32 [ [[OUTER_IV]], [[NO_INNER]] ], [ [[IV_NEXT_LCSSA]], [[OUTER_BACKEDGE_LOOPEXIT]] ]
253 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
254 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
255 ; CHECK:       failure:
256 ; CHECK-NEXT:    unreachable
257 ; CHECK:       side.exit:
258 ; CHECK-NEXT:    ret i32 0
259 ; CHECK:       exit:
260 ; CHECK-NEXT:    ret i32 1
262 entry:
263   %b_is_non_negative = icmp sge i32 %b, 0
264   br i1 %b_is_non_negative, label %outer, label %failure
266 outer:
267   %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge]
268   %outer_cond_1 = call i1 @cond()
269   br i1 %outer_cond_1, label %inner, label %no_inner
271 no_inner:
272   %outer_cond_2 = call i1 @cond()
273   br label %outer.backedge
275 inner:
276   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
277   %signed_cond = icmp slt i32 %iv, %b
278   br i1 %signed_cond, label %inner.1, label %side.exit
280 inner.1:
281   %unsigned_cond = icmp ult i32 %iv, %b
282   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
284 inner.backedge:
285   %iv.next = add nuw nsw i32 %iv, 1
286   %inner.loop.cond = call i1 @cond()
287   br i1 %inner.loop.cond, label %inner, label %outer.backedge
289 outer.backedge:
290   %outer.merge = phi i32 [%outer.iv, %no_inner], [%iv.next, %inner.backedge]
291   %outer.loop.cond = call i1 @cond()
292   br i1 %outer.loop.cond, label %outer, label %exit
294 failure:
295   unreachable
297 side.exit:
298   ret i32 0
300 exit:
301   ret i32 1
304 define i32 @test_04(i32 %a, i32 %b) {
305 ; CHECK-LABEL: @test_04(
306 ; CHECK-NEXT:  entry:
307 ; CHECK-NEXT:    [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0
308 ; CHECK-NEXT:    br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]]
309 ; CHECK:       outer.preheader:
310 ; CHECK-NEXT:    br label [[OUTER:%.*]]
311 ; CHECK:       outer:
312 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
313 ; CHECK-NEXT:    [[OUTER_COND_1:%.*]] = call i1 @cond()
314 ; CHECK-NEXT:    br i1 [[OUTER_COND_1]], label [[INNER_PREHEADER:%.*]], label [[NO_INNER:%.*]]
315 ; CHECK:       inner.preheader:
316 ; CHECK-NEXT:    br label [[INNER:%.*]]
317 ; CHECK:       no_inner:
318 ; CHECK-NEXT:    [[OUTER_COND_2:%.*]] = call i1 @cond()
319 ; CHECK-NEXT:    br i1 [[OUTER_COND_2]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
320 ; CHECK:       if.true:
321 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 [[OUTER_IV]])
322 ; CHECK-NEXT:    br label [[OUTER_BACKEDGE]]
323 ; CHECK:       if.false:
324 ; CHECK-NEXT:    br label [[OUTER_BACKEDGE]]
325 ; CHECK:       inner:
326 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ], [ [[OUTER_IV]], [[INNER_PREHEADER]] ]
327 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
328 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
329 ; CHECK:       inner.1:
330 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
331 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
332 ; CHECK:       inner.backedge:
333 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
334 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
335 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE_LOOPEXIT:%.*]]
336 ; CHECK:       outer.backedge.loopexit:
337 ; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
338 ; CHECK-NEXT:    br label [[OUTER_BACKEDGE]]
339 ; CHECK:       outer.backedge:
340 ; CHECK-NEXT:    [[OUTER_MERGE]] = phi i32 [ [[SMAX]], [[IF_TRUE]] ], [ [[OUTER_IV]], [[IF_FALSE]] ], [ [[IV_NEXT_LCSSA]], [[OUTER_BACKEDGE_LOOPEXIT]] ]
341 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
342 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
343 ; CHECK:       failure:
344 ; CHECK-NEXT:    unreachable
345 ; CHECK:       side.exit:
346 ; CHECK-NEXT:    ret i32 0
347 ; CHECK:       exit:
348 ; CHECK-NEXT:    ret i32 1
350 entry:
351   %b_is_non_negative = icmp sge i32 %b, 0
352   br i1 %b_is_non_negative, label %outer, label %failure
354 outer:
355   %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge]
356   %outer_cond_1 = call i1 @cond()
357   br i1 %outer_cond_1, label %inner, label %no_inner
359 no_inner:
360   %outer_cond_2 = call i1 @cond()
361   br i1 %outer_cond_2, label %if.true, label %if.false
363 if.true:
364   %smax = call i32 @llvm.smax.i32(i32 %a, i32 %outer.iv)
365   br label %outer.backedge
367 if.false:
368   br label %outer.backedge
370 inner:
371   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
372   %signed_cond = icmp slt i32 %iv, %b
373   br i1 %signed_cond, label %inner.1, label %side.exit
375 inner.1:
376   %unsigned_cond = icmp ult i32 %iv, %b
377   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
379 inner.backedge:
380   %iv.next = add nuw nsw i32 %iv, 1
381   %inner.loop.cond = call i1 @cond()
382   br i1 %inner.loop.cond, label %inner, label %outer.backedge
384 outer.backedge:
385   %outer.merge = phi i32 [%smax, %if.true], [%outer.iv, %if.false], [%iv.next, %inner.backedge]
386   %outer.loop.cond = call i1 @cond()
387   br i1 %outer.loop.cond, label %outer, label %exit
389 failure:
390   unreachable
392 side.exit:
393   ret i32 0
395 exit:
396   ret i32 1
399 ; Same as test_01, but non-negativity of %b is known without context.
400 ; FIXME: We can remove 2nd check in loop.
401 define i32 @test_05(i32 %a, ptr %bp) {
402 ; CHECK-LABEL: @test_05(
403 ; CHECK-NEXT:  entry:
404 ; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0:![0-9]+]]
405 ; CHECK-NEXT:    br label [[OUTER:%.*]]
406 ; CHECK:       outer:
407 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
408 ; CHECK-NEXT:    br label [[INNER:%.*]]
409 ; CHECK:       inner:
410 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
411 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
412 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
413 ; CHECK:       inner.1:
414 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]]
415 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
416 ; CHECK:       inner.backedge:
417 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
418 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
419 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
420 ; CHECK:       outer.backedge:
421 ; CHECK-NEXT:    [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
422 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
423 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
424 ; CHECK:       side.exit:
425 ; CHECK-NEXT:    ret i32 0
426 ; CHECK:       exit:
427 ; CHECK-NEXT:    ret i32 1
429 entry:
430   %b = load i32, ptr %bp, !range !0
431   br label %outer
433 outer:
434   %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
435   br label %inner
438 inner:
439   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
440   %signed_cond = icmp slt i32 %iv, %b
441   br i1 %signed_cond, label %inner.1, label %side.exit
443 inner.1:
444   %unsigned_cond = icmp ult i32 %iv, %b
445   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
447 inner.backedge:
448   %iv.next = add nuw nsw i32 %iv, 1
449   %inner.loop.cond = call i1 @cond()
450   br i1 %inner.loop.cond, label %inner, label %outer.backedge
452 outer.backedge:
453   %outer.loop.cond = call i1 @cond()
454   br i1 %outer.loop.cond, label %outer, label %exit
456 side.exit:
457   ret i32 0
459 exit:
460   ret i32 1
464 ; Same as test_01a, but non-negativity of %b is known without context.
465 define i32 @test_05a(i32 %a, ptr %bp) {
466 ; CHECK-LABEL: @test_05a(
467 ; CHECK-NEXT:  entry:
468 ; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
469 ; CHECK-NEXT:    br label [[OUTER:%.*]]
470 ; CHECK:       outer:
471 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
472 ; CHECK-NEXT:    br label [[INNER:%.*]]
473 ; CHECK:       inner:
474 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
475 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
476 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
477 ; CHECK:       inner.1:
478 ; CHECK-NEXT:    br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
479 ; CHECK:       inner.backedge:
480 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
481 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
482 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
483 ; CHECK:       outer.backedge:
484 ; CHECK-NEXT:    [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
485 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
486 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
487 ; CHECK:       side.exit:
488 ; CHECK-NEXT:    ret i32 0
489 ; CHECK:       exit:
490 ; CHECK-NEXT:    ret i32 1
492 entry:
493   %b = load i32, ptr %bp, !range !0
494   br label %outer
496 outer:
497   %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
498   br label %inner
501 inner:
502   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
503   %unsigned_cond = icmp ult i32 %iv, %b
504   br i1 %unsigned_cond, label %inner.1, label %side.exit
506 inner.1:
507   %signed_cond = icmp slt i32 %iv, %b
508   br i1 %signed_cond, label %inner.backedge, label %side.exit
510 inner.backedge:
511   %iv.next = add nuw nsw i32 %iv, 1
512   %inner.loop.cond = call i1 @cond()
513   br i1 %inner.loop.cond, label %inner, label %outer.backedge
515 outer.backedge:
516   %outer.loop.cond = call i1 @cond()
517   br i1 %outer.loop.cond, label %outer, label %exit
519 side.exit:
520   ret i32 0
522 exit:
523   ret i32 1
526 ; Similar to test_05a, but inverted 2nd condition.
527 define i32 @test_05b(i32 %a, ptr %bp) {
528 ; CHECK-LABEL: @test_05b(
529 ; CHECK-NEXT:  entry:
530 ; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
531 ; CHECK-NEXT:    br label [[OUTER:%.*]]
532 ; CHECK:       outer:
533 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
534 ; CHECK-NEXT:    br label [[INNER:%.*]]
535 ; CHECK:       inner:
536 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
537 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
538 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
539 ; CHECK:       inner.1:
540 ; CHECK-NEXT:    br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
541 ; CHECK:       inner.backedge:
542 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
543 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
544 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
545 ; CHECK:       outer.backedge:
546 ; CHECK-NEXT:    [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
547 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
548 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
549 ; CHECK:       side.exit:
550 ; CHECK-NEXT:    ret i32 0
551 ; CHECK:       exit:
552 ; CHECK-NEXT:    ret i32 1
554 entry:
555   %b = load i32, ptr %bp, !range !0
556   br label %outer
558 outer:
559   %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
560   br label %inner
563 inner:
564   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
565   %unsigned_cond = icmp ult i32 %iv, %b
566   br i1 %unsigned_cond, label %inner.1, label %side.exit
568 inner.1:
569   %signed_cond = icmp sgt i32 %b, %iv
570   br i1 %signed_cond, label %inner.backedge, label %side.exit
572 inner.backedge:
573   %iv.next = add nuw nsw i32 %iv, 1
574   %inner.loop.cond = call i1 @cond()
575   br i1 %inner.loop.cond, label %inner, label %outer.backedge
577 outer.backedge:
578   %outer.loop.cond = call i1 @cond()
579   br i1 %outer.loop.cond, label %outer, label %exit
581 side.exit:
582   ret i32 0
584 exit:
585   ret i32 1
588 ; We should prove implication: iv <s b, b <s 0 => iv <u b.
589 define i32 @test_05c(i32 %a, ptr %bp) {
590 ; CHECK-LABEL: @test_05c(
591 ; CHECK-NEXT:  entry:
592 ; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG1:![0-9]+]]
593 ; CHECK-NEXT:    br label [[OUTER:%.*]]
594 ; CHECK:       outer:
595 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
596 ; CHECK-NEXT:    br label [[INNER:%.*]]
597 ; CHECK:       inner:
598 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
599 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
600 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
601 ; CHECK:       inner.1:
602 ; CHECK-NEXT:    br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
603 ; CHECK:       inner.backedge:
604 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
605 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
606 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
607 ; CHECK:       outer.backedge:
608 ; CHECK-NEXT:    [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
609 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
610 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
611 ; CHECK:       side.exit:
612 ; CHECK-NEXT:    ret i32 0
613 ; CHECK:       exit:
614 ; CHECK-NEXT:    ret i32 1
616 entry:
617   %b = load i32, ptr %bp, !range !1
618   br label %outer
620 outer:
621   %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
622   br label %inner
625 inner:
626   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
627   %signed_cond = icmp slt i32 %iv, %b
628   br i1 %signed_cond, label %inner.1, label %side.exit
630 inner.1:
631   %unsigned_cond = icmp ult i32 %iv, %b
632   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
634 inner.backedge:
635   %iv.next = add nuw nsw i32 %iv, 1
636   %inner.loop.cond = call i1 @cond()
637   br i1 %inner.loop.cond, label %inner, label %outer.backedge
639 outer.backedge:
640   %outer.loop.cond = call i1 @cond()
641   br i1 %outer.loop.cond, label %outer, label %exit
643 side.exit:
644   ret i32 0
646 exit:
647   ret i32 1
650 ; Same as test_05c, but 2nd condition reversed.
651 define i32 @test_05d(i32 %a, ptr %bp) {
652 ; CHECK-LABEL: @test_05d(
653 ; CHECK-NEXT:  entry:
654 ; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG1]]
655 ; CHECK-NEXT:    br label [[OUTER:%.*]]
656 ; CHECK:       outer:
657 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
658 ; CHECK-NEXT:    br label [[INNER:%.*]]
659 ; CHECK:       inner:
660 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
661 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
662 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
663 ; CHECK:       inner.1:
664 ; CHECK-NEXT:    br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
665 ; CHECK:       inner.backedge:
666 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
667 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
668 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
669 ; CHECK:       outer.backedge:
670 ; CHECK-NEXT:    [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
671 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
672 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
673 ; CHECK:       side.exit:
674 ; CHECK-NEXT:    ret i32 0
675 ; CHECK:       exit:
676 ; CHECK-NEXT:    ret i32 1
678 entry:
679   %b = load i32, ptr %bp, !range !1
680   br label %outer
682 outer:
683   %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
684   br label %inner
687 inner:
688   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
689   %signed_cond = icmp slt i32 %iv, %b
690   br i1 %signed_cond, label %inner.1, label %side.exit
692 inner.1:
693   %unsigned_cond = icmp ugt i32 %b, %iv
694   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
696 inner.backedge:
697   %iv.next = add nuw nsw i32 %iv, 1
698   %inner.loop.cond = call i1 @cond()
699   br i1 %inner.loop.cond, label %inner, label %outer.backedge
701 outer.backedge:
702   %outer.loop.cond = call i1 @cond()
703   br i1 %outer.loop.cond, label %outer, label %exit
705 side.exit:
706   ret i32 0
708 exit:
709   ret i32 1
713 ; Same as test_05a, but 1st condition inverted.
714 define i32 @test_05e(i32 %a, ptr %bp) {
715 ; CHECK-LABEL: @test_05e(
716 ; CHECK-NEXT:  entry:
717 ; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
718 ; CHECK-NEXT:    br label [[OUTER:%.*]]
719 ; CHECK:       outer:
720 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
721 ; CHECK-NEXT:    br label [[INNER:%.*]]
722 ; CHECK:       inner:
723 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
724 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp ugt i32 [[B]], [[IV]]
725 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
726 ; CHECK:       inner.1:
727 ; CHECK-NEXT:    br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
728 ; CHECK:       inner.backedge:
729 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
730 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
731 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
732 ; CHECK:       outer.backedge:
733 ; CHECK-NEXT:    [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
734 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
735 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
736 ; CHECK:       side.exit:
737 ; CHECK-NEXT:    ret i32 0
738 ; CHECK:       exit:
739 ; CHECK-NEXT:    ret i32 1
741 entry:
742   %b = load i32, ptr %bp, !range !0
743   br label %outer
745 outer:
746   %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
747   br label %inner
750 inner:
751   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
752   %unsigned_cond = icmp ugt i32 %b, %iv
753   br i1 %unsigned_cond, label %inner.1, label %side.exit
755 inner.1:
756   %signed_cond = icmp slt i32 %iv, %b
757   br i1 %signed_cond, label %inner.backedge, label %side.exit
759 inner.backedge:
760   %iv.next = add nuw nsw i32 %iv, 1
761   %inner.loop.cond = call i1 @cond()
762   br i1 %inner.loop.cond, label %inner, label %outer.backedge
764 outer.backedge:
765   %outer.loop.cond = call i1 @cond()
766   br i1 %outer.loop.cond, label %outer, label %exit
768 side.exit:
769   ret i32 0
771 exit:
772   ret i32 1
775 ; Same as test_05b, but 1st condition inverted.
776 define i32 @test_05f(i32 %a, ptr %bp) {
777 ; CHECK-LABEL: @test_05f(
778 ; CHECK-NEXT:  entry:
779 ; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
780 ; CHECK-NEXT:    br label [[OUTER:%.*]]
781 ; CHECK:       outer:
782 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
783 ; CHECK-NEXT:    br label [[INNER:%.*]]
784 ; CHECK:       inner:
785 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
786 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp ugt i32 [[B]], [[IV]]
787 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
788 ; CHECK:       inner.1:
789 ; CHECK-NEXT:    br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
790 ; CHECK:       inner.backedge:
791 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
792 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
793 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
794 ; CHECK:       outer.backedge:
795 ; CHECK-NEXT:    [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
796 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
797 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
798 ; CHECK:       side.exit:
799 ; CHECK-NEXT:    ret i32 0
800 ; CHECK:       exit:
801 ; CHECK-NEXT:    ret i32 1
803 entry:
804   %b = load i32, ptr %bp, !range !0
805   br label %outer
807 outer:
808   %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
809   br label %inner
812 inner:
813   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
814   %unsigned_cond = icmp ugt i32 %b, %iv
815   br i1 %unsigned_cond, label %inner.1, label %side.exit
817 inner.1:
818   %signed_cond = icmp sgt i32 %b, %iv
819   br i1 %signed_cond, label %inner.backedge, label %side.exit
821 inner.backedge:
822   %iv.next = add nuw nsw i32 %iv, 1
823   %inner.loop.cond = call i1 @cond()
824   br i1 %inner.loop.cond, label %inner, label %outer.backedge
826 outer.backedge:
827   %outer.loop.cond = call i1 @cond()
828   br i1 %outer.loop.cond, label %outer, label %exit
830 side.exit:
831   ret i32 0
833 exit:
834   ret i32 1
837 ; Same as test_05c, but 1st condition inverted.
838 define i32 @test_05g(i32 %a, ptr %bp) {
839 ; CHECK-LABEL: @test_05g(
840 ; CHECK-NEXT:  entry:
841 ; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG1]]
842 ; CHECK-NEXT:    br label [[OUTER:%.*]]
843 ; CHECK:       outer:
844 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
845 ; CHECK-NEXT:    br label [[INNER:%.*]]
846 ; CHECK:       inner:
847 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
848 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp sgt i32 [[B]], [[IV]]
849 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
850 ; CHECK:       inner.1:
851 ; CHECK-NEXT:    br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
852 ; CHECK:       inner.backedge:
853 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
854 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
855 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
856 ; CHECK:       outer.backedge:
857 ; CHECK-NEXT:    [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
858 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
859 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
860 ; CHECK:       side.exit:
861 ; CHECK-NEXT:    ret i32 0
862 ; CHECK:       exit:
863 ; CHECK-NEXT:    ret i32 1
865 entry:
866   %b = load i32, ptr %bp, !range !1
867   br label %outer
869 outer:
870   %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
871   br label %inner
874 inner:
875   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
876   %signed_cond = icmp sgt i32 %b, %iv
877   br i1 %signed_cond, label %inner.1, label %side.exit
879 inner.1:
880   %unsigned_cond = icmp ult i32 %iv, %b
881   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
883 inner.backedge:
884   %iv.next = add nuw nsw i32 %iv, 1
885   %inner.loop.cond = call i1 @cond()
886   br i1 %inner.loop.cond, label %inner, label %outer.backedge
888 outer.backedge:
889   %outer.loop.cond = call i1 @cond()
890   br i1 %outer.loop.cond, label %outer, label %exit
892 side.exit:
893   ret i32 0
895 exit:
896   ret i32 1
899 ; Same as test_05d, but 1st condition inverted.
900 define i32 @test_05h(i32 %a, ptr %bp) {
901 ; CHECK-LABEL: @test_05h(
902 ; CHECK-NEXT:  entry:
903 ; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG1]]
904 ; CHECK-NEXT:    br label [[OUTER:%.*]]
905 ; CHECK:       outer:
906 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
907 ; CHECK-NEXT:    br label [[INNER:%.*]]
908 ; CHECK:       inner:
909 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
910 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp sgt i32 [[B]], [[IV]]
911 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
912 ; CHECK:       inner.1:
913 ; CHECK-NEXT:    br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
914 ; CHECK:       inner.backedge:
915 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
916 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
917 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
918 ; CHECK:       outer.backedge:
919 ; CHECK-NEXT:    [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
920 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
921 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
922 ; CHECK:       side.exit:
923 ; CHECK-NEXT:    ret i32 0
924 ; CHECK:       exit:
925 ; CHECK-NEXT:    ret i32 1
927 entry:
928   %b = load i32, ptr %bp, !range !1
929   br label %outer
931 outer:
932   %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
933   br label %inner
936 inner:
937   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
938   %signed_cond = icmp sgt i32 %b, %iv
939   br i1 %signed_cond, label %inner.1, label %side.exit
941 inner.1:
942   %unsigned_cond = icmp ugt i32 %b, %iv
943   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
945 inner.backedge:
946   %iv.next = add nuw nsw i32 %iv, 1
947   %inner.loop.cond = call i1 @cond()
948   br i1 %inner.loop.cond, label %inner, label %outer.backedge
950 outer.backedge:
951   %outer.loop.cond = call i1 @cond()
952   br i1 %outer.loop.cond, label %outer, label %exit
954 side.exit:
955   ret i32 0
957 exit:
958   ret i32 1
961 ; Same as test_02, but non-negativity of %b is known without context.
962 ; FIXME: We can remove 2nd check in loop.
963 define i32 @test_06(i32 %a, ptr %bp) {
964 ; CHECK-LABEL: @test_06(
965 ; CHECK-NEXT:  entry:
966 ; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
967 ; CHECK-NEXT:    br label [[OUTER:%.*]]
968 ; CHECK:       outer:
969 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ]
970 ; CHECK-NEXT:    br label [[INNER:%.*]]
971 ; CHECK:       inner:
972 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
973 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
974 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
975 ; CHECK:       inner.1:
976 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]]
977 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
978 ; CHECK:       inner.backedge:
979 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
980 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
981 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
982 ; CHECK:       outer.backedge:
983 ; CHECK-NEXT:    [[OUTER_MERGE]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
984 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
985 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
986 ; CHECK:       side.exit:
987 ; CHECK-NEXT:    ret i32 0
988 ; CHECK:       exit:
989 ; CHECK-NEXT:    ret i32 1
991 entry:
992   %b = load i32, ptr %bp, !range !0
993   br label %outer
995 outer:
996   %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge]
997   br label %inner
1000 inner:
1001   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
1002   %signed_cond = icmp slt i32 %iv, %b
1003   br i1 %signed_cond, label %inner.1, label %side.exit
1005 inner.1:
1006   %unsigned_cond = icmp ult i32 %iv, %b
1007   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
1009 inner.backedge:
1010   %iv.next = add nuw nsw i32 %iv, 1
1011   %inner.loop.cond = call i1 @cond()
1012   br i1 %inner.loop.cond, label %inner, label %outer.backedge
1014 outer.backedge:
1015   %outer.merge = phi i32 [%iv.next, %inner.backedge]
1016   %outer.loop.cond = call i1 @cond()
1017   br i1 %outer.loop.cond, label %outer, label %exit
1019 side.exit:
1020   ret i32 0
1022 exit:
1023   ret i32 1
1026 ; Same as test_03, but non-negativity of %b is known without context.
1027 ; FIXME: We can remove 2nd check in loop.
1028 define i32 @test_07(i32 %a, ptr %bp) {
1029 ; CHECK-LABEL: @test_07(
1030 ; CHECK-NEXT:  entry:
1031 ; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
1032 ; CHECK-NEXT:    br label [[OUTER:%.*]]
1033 ; CHECK:       outer:
1034 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ]
1035 ; CHECK-NEXT:    [[OUTER_COND_1:%.*]] = call i1 @cond()
1036 ; CHECK-NEXT:    br i1 [[OUTER_COND_1]], label [[INNER_PREHEADER:%.*]], label [[NO_INNER:%.*]]
1037 ; CHECK:       inner.preheader:
1038 ; CHECK-NEXT:    br label [[INNER:%.*]]
1039 ; CHECK:       no_inner:
1040 ; CHECK-NEXT:    [[OUTER_COND_2:%.*]] = call i1 @cond()
1041 ; CHECK-NEXT:    br label [[OUTER_BACKEDGE]]
1042 ; CHECK:       inner:
1043 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ], [ [[OUTER_IV]], [[INNER_PREHEADER]] ]
1044 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
1045 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
1046 ; CHECK:       inner.1:
1047 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]]
1048 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
1049 ; CHECK:       inner.backedge:
1050 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
1051 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
1052 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE_LOOPEXIT:%.*]]
1053 ; CHECK:       outer.backedge.loopexit:
1054 ; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
1055 ; CHECK-NEXT:    br label [[OUTER_BACKEDGE]]
1056 ; CHECK:       outer.backedge:
1057 ; CHECK-NEXT:    [[OUTER_MERGE]] = phi i32 [ [[OUTER_IV]], [[NO_INNER]] ], [ [[IV_NEXT_LCSSA]], [[OUTER_BACKEDGE_LOOPEXIT]] ]
1058 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
1059 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
1060 ; CHECK:       side.exit:
1061 ; CHECK-NEXT:    ret i32 0
1062 ; CHECK:       exit:
1063 ; CHECK-NEXT:    ret i32 1
1065 entry:
1066   %b = load i32, ptr %bp, !range !0
1067   br label %outer
1069 outer:
1070   %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge]
1071   %outer_cond_1 = call i1 @cond()
1072   br i1 %outer_cond_1, label %inner, label %no_inner
1074 no_inner:
1075   %outer_cond_2 = call i1 @cond()
1076   br label %outer.backedge
1078 inner:
1079   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
1080   %signed_cond = icmp slt i32 %iv, %b
1081   br i1 %signed_cond, label %inner.1, label %side.exit
1083 inner.1:
1084   %unsigned_cond = icmp ult i32 %iv, %b
1085   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
1087 inner.backedge:
1088   %iv.next = add nuw nsw i32 %iv, 1
1089   %inner.loop.cond = call i1 @cond()
1090   br i1 %inner.loop.cond, label %inner, label %outer.backedge
1092 outer.backedge:
1093   %outer.merge = phi i32 [%outer.iv, %no_inner], [%iv.next, %inner.backedge]
1094   %outer.loop.cond = call i1 @cond()
1095   br i1 %outer.loop.cond, label %outer, label %exit
1097 side.exit:
1098   ret i32 0
1100 exit:
1101   ret i32 1
1104 ; Same as test_04, but non-negativity of %b is known without context.
1105 ; FIXME: We can remove 2nd check in loop.
1106 define i32 @test_08(i32 %a, ptr %bp) {
1107 ; CHECK-LABEL: @test_08(
1108 ; CHECK-NEXT:  entry:
1109 ; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
1110 ; CHECK-NEXT:    br label [[OUTER:%.*]]
1111 ; CHECK:       outer:
1112 ; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ]
1113 ; CHECK-NEXT:    [[OUTER_COND_1:%.*]] = call i1 @cond()
1114 ; CHECK-NEXT:    br i1 [[OUTER_COND_1]], label [[INNER_PREHEADER:%.*]], label [[NO_INNER:%.*]]
1115 ; CHECK:       inner.preheader:
1116 ; CHECK-NEXT:    br label [[INNER:%.*]]
1117 ; CHECK:       no_inner:
1118 ; CHECK-NEXT:    [[OUTER_COND_2:%.*]] = call i1 @cond()
1119 ; CHECK-NEXT:    br i1 [[OUTER_COND_2]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1120 ; CHECK:       if.true:
1121 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 [[OUTER_IV]])
1122 ; CHECK-NEXT:    br label [[OUTER_BACKEDGE]]
1123 ; CHECK:       if.false:
1124 ; CHECK-NEXT:    br label [[OUTER_BACKEDGE]]
1125 ; CHECK:       inner:
1126 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ], [ [[OUTER_IV]], [[INNER_PREHEADER]] ]
1127 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
1128 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
1129 ; CHECK:       inner.1:
1130 ; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]]
1131 ; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
1132 ; CHECK:       inner.backedge:
1133 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
1134 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
1135 ; CHECK-NEXT:    br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE_LOOPEXIT:%.*]]
1136 ; CHECK:       outer.backedge.loopexit:
1137 ; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
1138 ; CHECK-NEXT:    br label [[OUTER_BACKEDGE]]
1139 ; CHECK:       outer.backedge:
1140 ; CHECK-NEXT:    [[OUTER_MERGE]] = phi i32 [ [[SMAX]], [[IF_TRUE]] ], [ [[OUTER_IV]], [[IF_FALSE]] ], [ [[IV_NEXT_LCSSA]], [[OUTER_BACKEDGE_LOOPEXIT]] ]
1141 ; CHECK-NEXT:    [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
1142 ; CHECK-NEXT:    br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
1143 ; CHECK:       side.exit:
1144 ; CHECK-NEXT:    ret i32 0
1145 ; CHECK:       exit:
1146 ; CHECK-NEXT:    ret i32 1
1148 entry:
1149   %b = load i32, ptr %bp, !range !0
1150   br label %outer
1152 outer:
1153   %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge]
1154   %outer_cond_1 = call i1 @cond()
1155   br i1 %outer_cond_1, label %inner, label %no_inner
1157 no_inner:
1158   %outer_cond_2 = call i1 @cond()
1159   br i1 %outer_cond_2, label %if.true, label %if.false
1161 if.true:
1162   %smax = call i32 @llvm.smax.i32(i32 %a, i32 %outer.iv)
1163   br label %outer.backedge
1165 if.false:
1166   br label %outer.backedge
1168 inner:
1169   %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
1170   %signed_cond = icmp slt i32 %iv, %b
1171   br i1 %signed_cond, label %inner.1, label %side.exit
1173 inner.1:
1174   %unsigned_cond = icmp ult i32 %iv, %b
1175   br i1 %unsigned_cond, label %inner.backedge, label %side.exit
1177 inner.backedge:
1178   %iv.next = add nuw nsw i32 %iv, 1
1179   %inner.loop.cond = call i1 @cond()
1180   br i1 %inner.loop.cond, label %inner, label %outer.backedge
1182 outer.backedge:
1183   %outer.merge = phi i32 [%smax, %if.true], [%outer.iv, %if.false], [%iv.next, %inner.backedge]
1184   %outer.loop.cond = call i1 @cond()
1185   br i1 %outer.loop.cond, label %outer, label %exit
1187 side.exit:
1188   ret i32 0
1190 exit:
1191   ret i32 1
1194 !0 = !{i32 0, i32 2147483647}
1195 !1 = !{i32 -2147483648, i32 0}