[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / IndVarSimplify / X86 / loop-invariant-conditions.ll
blob8b80f8e518808f2843810a378f782392e1b4b449
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -indvars -indvars-predicate-loops=0 %s | FileCheck %s
3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-unknown-linux-gnu"
6 define void @test1(i64 %start) {
7 ; CHECK-LABEL: @test1(
8 ; CHECK-NEXT:  entry:
9 ; CHECK-NEXT:    br label [[LOOP:%.*]]
10 ; CHECK:       loop:
11 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i64 [[START:%.*]], -1
12 ; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]]
13 ; CHECK:       for.end:
14 ; CHECK-NEXT:    ret void
16 entry:
17   br label %loop
19 loop:
20   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
21   %indvars.iv.next = add nsw i64 %indvars.iv, 1
22   %cmp1 = icmp slt i64 %indvars.iv, -1
23   br i1 %cmp1, label %for.end, label %loop
25 for.end:                                          ; preds = %if.end, %entry
26   ret void
29 define void @test2(i64 %start) {
30 ; CHECK-LABEL: @test2(
31 ; CHECK-NEXT:  entry:
32 ; CHECK-NEXT:    br label [[LOOP:%.*]]
33 ; CHECK:       loop:
34 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sle i64 [[START:%.*]], -1
35 ; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]]
36 ; CHECK:       for.end:
37 ; CHECK-NEXT:    ret void
39 entry:
40   br label %loop
42 loop:
43   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
44   %indvars.iv.next = add nsw i64 %indvars.iv, 1
45   %cmp1 = icmp sle i64 %indvars.iv, -1
46   br i1 %cmp1, label %for.end, label %loop
48 for.end:                                          ; preds = %if.end, %entry
49   ret void
52 ; As long as the test dominates the backedge, we're good
53 define void @test3(i64 %start) {
54 ; CHECK-LABEL: @test3(
55 ; CHECK-NEXT:  entry:
56 ; CHECK-NEXT:    br label [[LOOP:%.*]]
57 ; CHECK:       loop:
58 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
59 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
60 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
61 ; CHECK-NEXT:    br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]]
62 ; CHECK:       backedge:
63 ; CHECK-NEXT:    call void @foo()
64 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i64 [[START]], -1
65 ; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_END]], label [[LOOP]]
66 ; CHECK:       for.end:
67 ; CHECK-NEXT:    ret void
69 entry:
70   br label %loop
72 loop:
73   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
74   %indvars.iv.next = add nsw i64 %indvars.iv, 1
75   %cmp = icmp eq i64 %indvars.iv.next, 25
76   br i1 %cmp, label %backedge, label %for.end
78 backedge:
79   ; prevent flattening, needed to make sure we're testing what we intend
80   call void @foo()
81   %cmp1 = icmp slt i64 %indvars.iv, -1
82   br i1 %cmp1, label %for.end, label %loop
84 for.end:                                          ; preds = %if.end, %entry
85   ret void
88 define void @test4(i64 %start) {
89 ; CHECK-LABEL: @test4(
90 ; CHECK-NEXT:  entry:
91 ; CHECK-NEXT:    br label [[LOOP:%.*]]
92 ; CHECK:       loop:
93 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
94 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
95 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
96 ; CHECK-NEXT:    br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]]
97 ; CHECK:       backedge:
98 ; CHECK-NEXT:    call void @foo()
99 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i64 [[START]], -1
100 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LOOP]], label [[FOR_END]]
101 ; CHECK:       for.end:
102 ; CHECK-NEXT:    ret void
104 entry:
105   br label %loop
107 loop:
108   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
109   %indvars.iv.next = add nsw i64 %indvars.iv, 1
110   %cmp = icmp eq i64 %indvars.iv.next, 25
111   br i1 %cmp, label %backedge, label %for.end
113 backedge:
114   ; prevent flattening, needed to make sure we're testing what we intend
115   call void @foo()
116   %cmp1 = icmp sgt i64 %indvars.iv, -1
117   br i1 %cmp1, label %loop, label %for.end
119 for.end:                                          ; preds = %if.end, %entry
120   ret void
123 define void @test5(i64 %start) {
124 ; CHECK-LABEL: @test5(
125 ; CHECK-NEXT:  entry:
126 ; CHECK-NEXT:    br label [[LOOP:%.*]]
127 ; CHECK:       loop:
128 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
129 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw i64 [[INDVARS_IV]], 1
130 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
131 ; CHECK-NEXT:    br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]]
132 ; CHECK:       backedge:
133 ; CHECK-NEXT:    call void @foo()
134 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i64 [[START]], 100
135 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LOOP]], label [[FOR_END]]
136 ; CHECK:       for.end:
137 ; CHECK-NEXT:    ret void
139 entry:
140   br label %loop
142 loop:
143   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
144   %indvars.iv.next = add nuw i64 %indvars.iv, 1
145   %cmp = icmp eq i64 %indvars.iv.next, 25
146   br i1 %cmp, label %backedge, label %for.end
148 backedge:
149   ; prevent flattening, needed to make sure we're testing what we intend
150   call void @foo()
151   %cmp1 = icmp ugt i64 %indvars.iv, 100
152   br i1 %cmp1, label %loop, label %for.end
154 for.end:                                          ; preds = %if.end, %entry
155   ret void
158 define void @test6(i64 %start) {
159 ; CHECK-LABEL: @test6(
160 ; CHECK-NEXT:  entry:
161 ; CHECK-NEXT:    br label [[LOOP:%.*]]
162 ; CHECK:       loop:
163 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
164 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw i64 [[INDVARS_IV]], 1
165 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
166 ; CHECK-NEXT:    br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]]
167 ; CHECK:       backedge:
168 ; CHECK-NEXT:    call void @foo()
169 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[START]], 100
170 ; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_END]], label [[LOOP]]
171 ; CHECK:       for.end:
172 ; CHECK-NEXT:    ret void
174 entry:
175   br label %loop
177 loop:
178   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
179   %indvars.iv.next = add nuw i64 %indvars.iv, 1
180   %cmp = icmp eq i64 %indvars.iv.next, 25
181   br i1 %cmp, label %backedge, label %for.end
183 backedge:
184   ; prevent flattening, needed to make sure we're testing what we intend
185   call void @foo()
186   %cmp1 = icmp ult i64 %indvars.iv, 100
187   br i1 %cmp1, label %for.end, label %loop
189 for.end:                                          ; preds = %if.end, %entry
190   ret void
193 define void @test7(i64 %start, i64* %inc_ptr) {
194 ; CHECK-LABEL: @test7(
195 ; CHECK-NEXT:  entry:
196 ; CHECK-NEXT:    [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], align 8, !range [[RNG0:![0-9]+]]
197 ; CHECK-NEXT:    [[OK:%.*]] = icmp sge i64 [[INC]], 0
198 ; CHECK-NEXT:    br i1 [[OK]], label [[LOOP_PREHEADER:%.*]], label [[FOR_END:%.*]]
199 ; CHECK:       loop.preheader:
200 ; CHECK-NEXT:    br label [[LOOP:%.*]]
201 ; CHECK:       loop:
202 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i64 [[START:%.*]], -1
203 ; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_END_LOOPEXIT:%.*]], label [[LOOP]]
204 ; CHECK:       for.end.loopexit:
205 ; CHECK-NEXT:    br label [[FOR_END]]
206 ; CHECK:       for.end:
207 ; CHECK-NEXT:    ret void
209 entry:
210   %inc = load i64, i64* %inc_ptr, !range !0
211   %ok = icmp sge i64 %inc, 0
212   br i1 %ok, label %loop, label %for.end
214 loop:
215   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
216   %indvars.iv.next = add nsw i64 %indvars.iv, %inc
217   %cmp1 = icmp slt i64 %indvars.iv, -1
218   br i1 %cmp1, label %for.end, label %loop
220 for.end:                                          ; preds = %if.end, %entry
221   ret void
224 ; Negative test - we can't show that the internal branch executes, so we can't
225 ; fold the test to a loop invariant one.
226 define void @test1_neg(i64 %start) {
227 ; CHECK-LABEL: @test1_neg(
228 ; CHECK-NEXT:  entry:
229 ; CHECK-NEXT:    br label [[LOOP:%.*]]
230 ; CHECK:       loop:
231 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
232 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
233 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
234 ; CHECK-NEXT:    br i1 [[CMP]], label [[BACKEDGE]], label [[SKIP:%.*]]
235 ; CHECK:       skip:
236 ; CHECK-NEXT:    call void @foo()
237 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1
238 ; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_END:%.*]], label [[BACKEDGE]]
239 ; CHECK:       backedge:
240 ; CHECK-NEXT:    call void @foo()
241 ; CHECK-NEXT:    br label [[LOOP]]
242 ; CHECK:       for.end:
243 ; CHECK-NEXT:    ret void
245 entry:
246   br label %loop
248 loop:
249   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
250   %indvars.iv.next = add nsw i64 %indvars.iv, 1
251   %cmp = icmp eq i64 %indvars.iv.next, 25
252   br i1 %cmp, label %backedge, label %skip
253 skip:
254   ; prevent flattening, needed to make sure we're testing what we intend
255   call void @foo()
256   %cmp1 = icmp slt i64 %indvars.iv, -1
257   br i1 %cmp1, label %for.end, label %backedge
258 backedge:
259   ; prevent flattening, needed to make sure we're testing what we intend
260   call void @foo()
261   br label %loop
263 for.end:                                          ; preds = %if.end, %entry
264   ret void
267 ; Slightly subtle version of @test4 where the icmp dominates the backedge,
268 ; but the exit branch doesn't.
269 define void @test2_neg(i64 %start) {
270 ; CHECK-LABEL: @test2_neg(
271 ; CHECK-NEXT:  entry:
272 ; CHECK-NEXT:    br label [[LOOP:%.*]]
273 ; CHECK:       loop:
274 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
275 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
276 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
277 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1
278 ; CHECK-NEXT:    br i1 [[CMP]], label [[BACKEDGE]], label [[SKIP:%.*]]
279 ; CHECK:       skip:
280 ; CHECK-NEXT:    call void @foo()
281 ; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_END:%.*]], label [[BACKEDGE]]
282 ; CHECK:       backedge:
283 ; CHECK-NEXT:    call void @foo()
284 ; CHECK-NEXT:    br label [[LOOP]]
285 ; CHECK:       for.end:
286 ; CHECK-NEXT:    ret void
288 entry:
289   br label %loop
291 loop:
292   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
293   %indvars.iv.next = add nsw i64 %indvars.iv, 1
294   %cmp = icmp eq i64 %indvars.iv.next, 25
295   %cmp1 = icmp slt i64 %indvars.iv, -1
296   br i1 %cmp, label %backedge, label %skip
297 skip:
298   ; prevent flattening, needed to make sure we're testing what we intend
299   call void @foo()
300   br i1 %cmp1, label %for.end, label %backedge
301 backedge:
302   ; prevent flattening, needed to make sure we're testing what we intend
303   call void @foo()
304   br label %loop
306 for.end:                                          ; preds = %if.end, %entry
307   ret void
310 ; The branch has to exit the loop if the condition is true
311 define void @test3_neg(i64 %start) {
312 ; CHECK-LABEL: @test3_neg(
313 ; CHECK-NEXT:  entry:
314 ; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[START:%.*]], i64 -1)
315 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[SMAX]], 1
316 ; CHECK-NEXT:    br label [[LOOP:%.*]]
317 ; CHECK:       loop:
318 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
319 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
320 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[TMP0]]
321 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[FOR_END:%.*]]
322 ; CHECK:       for.end:
323 ; CHECK-NEXT:    ret void
325 entry:
326   br label %loop
328 loop:
329   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
330   %indvars.iv.next = add nsw i64 %indvars.iv, 1
331   %cmp1 = icmp slt i64 %indvars.iv, -1
332   br i1 %cmp1, label %loop, label %for.end
334 for.end:                                          ; preds = %if.end, %entry
335   ret void
338 define void @test4_neg(i64 %start) {
339 ; CHECK-LABEL: @test4_neg(
340 ; CHECK-NEXT:  entry:
341 ; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[START:%.*]], i64 0)
342 ; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i64 [[SMAX]], 1
343 ; CHECK-NEXT:    br label [[LOOP:%.*]]
344 ; CHECK:       loop:
345 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
346 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
347 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
348 ; CHECK-NEXT:    br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]]
349 ; CHECK:       backedge:
350 ; CHECK-NEXT:    call void @foo()
351 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[TMP0]]
352 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[LOOP]]
353 ; CHECK:       for.end:
354 ; CHECK-NEXT:    ret void
356 entry:
357   br label %loop
359 loop:
360   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
361   %indvars.iv.next = add nsw i64 %indvars.iv, 1
362   %cmp = icmp eq i64 %indvars.iv.next, 25
363   br i1 %cmp, label %backedge, label %for.end
365 backedge:
366   ; prevent flattening, needed to make sure we're testing what we intend
367   call void @foo()
368   %cmp1 = icmp sgt i64 %indvars.iv, -1
370 ; %cmp1 can be made loop invariant only if the branch below goes to
371 ; %the header when %cmp1 is true.
372   br i1 %cmp1, label %for.end, label %loop
374 for.end:                                          ; preds = %if.end, %entry
375   ret void
378 define void @test5_neg(i64 %start, i64 %inc) {
379 ; CHECK-LABEL: @test5_neg(
380 ; CHECK-NEXT:  entry:
381 ; CHECK-NEXT:    br label [[LOOP:%.*]]
382 ; CHECK:       loop:
383 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
384 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], [[INC:%.*]]
385 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1
386 ; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]]
387 ; CHECK:       for.end:
388 ; CHECK-NEXT:    ret void
390 entry:
391   br label %loop
393 loop:
394   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
395   %indvars.iv.next = add nsw i64 %indvars.iv, %inc
396   %cmp1 = icmp slt i64 %indvars.iv, -1
397   br i1 %cmp1, label %for.end, label %loop
399 for.end:                                          ; preds = %if.end, %entry
400   ret void
403 define void @test8(i64 %start, i64* %inc_ptr) {
404 ; CHECK-LABEL: @test8(
405 ; CHECK-NEXT:  entry:
406 ; CHECK-NEXT:    [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], align 8, !range [[RNG1:![0-9]+]]
407 ; CHECK-NEXT:    [[OK:%.*]] = icmp sge i64 [[INC]], 0
408 ; CHECK-NEXT:    br i1 [[OK]], label [[LOOP_PREHEADER:%.*]], label [[FOR_END:%.*]]
409 ; CHECK:       loop.preheader:
410 ; CHECK-NEXT:    br label [[LOOP:%.*]]
411 ; CHECK:       loop:
412 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
413 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], [[INC]]
414 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1
415 ; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_END_LOOPEXIT:%.*]], label [[LOOP]]
416 ; CHECK:       for.end.loopexit:
417 ; CHECK-NEXT:    br label [[FOR_END]]
418 ; CHECK:       for.end:
419 ; CHECK-NEXT:    ret void
421 entry:
422   %inc = load i64, i64* %inc_ptr, !range !1
423   %ok = icmp sge i64 %inc, 0
424   br i1 %ok, label %loop, label %for.end
426 loop:
427   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
428   %indvars.iv.next = add nsw i64 %indvars.iv, %inc
429   %cmp1 = icmp slt i64 %indvars.iv, -1
430   br i1 %cmp1, label %for.end, label %loop
432 for.end:                                          ; preds = %if.end, %entry
433   ret void
436 ; check to handle loops without preheaders, but invariant operands
437 ; (we handle this today by inserting a preheader)
438 define void @test9(i1 %cnd, i64 %start) {
439 ; CHECK-LABEL: @test9(
440 ; CHECK-NEXT:  entry:
441 ; CHECK-NEXT:    br i1 [[CND:%.*]], label [[ENTRY1:%.*]], label [[ENTRY2:%.*]]
442 ; CHECK:       entry1:
443 ; CHECK-NEXT:    br label [[LOOP_PREHEADER:%.*]]
444 ; CHECK:       entry2:
445 ; CHECK-NEXT:    br label [[LOOP_PREHEADER]]
446 ; CHECK:       loop.preheader:
447 ; CHECK-NEXT:    br label [[LOOP:%.*]]
448 ; CHECK:       loop:
449 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i64 [[START:%.*]], -1
450 ; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]]
451 ; CHECK:       for.end:
452 ; CHECK-NEXT:    ret void
454 entry:
455   br i1 %cnd, label %entry1, label %entry2
456 entry1:
457   br label %loop
458 entry2:
459   br label %loop
460 loop:
461   %indvars.iv = phi i64 [ %start, %entry1 ],[ %start, %entry2 ], [ %indvars.iv.next, %loop ]
462   %indvars.iv.next = add nsw i64 %indvars.iv, 1
463   %cmp1 = icmp slt i64 %indvars.iv, -1
464   br i1 %cmp1, label %for.end, label %loop
466 for.end:                                          ; preds = %if.end, %entry
467   ret void
470 declare void @use(i1 %x)
472 ; check that we handle conditions with loop invariant operands which
473 ; *aren't* in the header - this is a very rare and fragile case where
474 ; we have a "loop" which is known to run exactly one iteration but
475 ; haven't yet simplified the uses of the IV
476 define void @test10() {
477 ; CHECK-LABEL: @test10(
478 ; CHECK-NEXT:  entry:
479 ; CHECK-NEXT:    br label [[LOOP:%.*]]
480 ; CHECK:       loop:
481 ; CHECK-NEXT:    [[PHI1:%.*]] = phi i32 [ [[PHI2:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
482 ; CHECK-NEXT:    [[DEC:%.*]] = add nuw nsw i32 [[PHI1]], -1
483 ; CHECK-NEXT:    br i1 false, label [[LEFT:%.*]], label [[RIGHT:%.*]]
484 ; CHECK:       left:
485 ; CHECK-NEXT:    br label [[LATCH]]
486 ; CHECK:       right:
487 ; CHECK-NEXT:    br label [[LATCH]]
488 ; CHECK:       latch:
489 ; CHECK-NEXT:    [[PHI2]] = phi i32 [ [[PHI1]], [[LEFT]] ], [ [[DEC]], [[RIGHT]] ]
490 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 -1, undef
491 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[LOOP]]
492 ; CHECK:       exit:
493 ; CHECK-NEXT:    [[CMP_LCSSA:%.*]] = phi i1 [ [[CMP]], [[LATCH]] ]
494 ; CHECK-NEXT:    call void @use(i1 [[CMP_LCSSA]])
495 ; CHECK-NEXT:    ret void
497 entry:
498   br label %loop
500 loop:
501   %phi1 = phi i32 [ %phi2, %latch ], [ 0, %entry ]
502   %dec = add i32 %phi1, -1
503   br i1 false, label %left, label %right
505 left:
506   br label %latch
508 right:
509   br label %latch
511 latch:
512   %phi2 = phi i32 [ %phi1, %left ], [ %dec, %right ]
513   %cmp = icmp slt i32 %phi2, undef
514   br i1 true, label %exit, label %loop
516 exit:
517   call void @use(i1 %cmp)
518   ret void
521 ; check that we can figure out that iv.next > 1 from the facts that iv >= 0 and
522 ; iv.start != 0.
523 define void @test11(i64* %inc_ptr) {
524 ; CHECK-LABEL: @test11(
525 ; CHECK-NEXT:  entry:
526 ; CHECK-NEXT:    [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], align 8, !range [[RNG0]]
527 ; CHECK-NEXT:    [[NE_COND:%.*]] = icmp ne i64 [[INC]], 0
528 ; CHECK-NEXT:    br i1 [[NE_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
529 ; CHECK:       loop.preheader:
530 ; CHECK-NEXT:    br label [[LOOP:%.*]]
531 ; CHECK:       loop:
532 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[INC]], [[LOOP_PREHEADER]] ]
533 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
534 ; CHECK-NEXT:    br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
535 ; CHECK:       if.true:
536 ; CHECK-NEXT:    br label [[BACKEDGE]]
537 ; CHECK:       if.false:
538 ; CHECK-NEXT:    br label [[BACKEDGE]]
539 ; CHECK:       backedge:
540 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], 201
541 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
542 ; CHECK:       exit.loopexit:
543 ; CHECK-NEXT:    br label [[EXIT]]
544 ; CHECK:       exit:
545 ; CHECK-NEXT:    ret void
547 entry:
548   %inc = load i64, i64* %inc_ptr, !range !0
549   %ne.cond = icmp ne i64 %inc, 0
550   br i1 %ne.cond, label %loop, label %exit
552 loop:
553   %iv = phi i64 [ %inc, %entry ], [ %iv.next, %backedge ]
554   %iv.next = add i64 %iv, 1
555   %brcond = icmp sgt i64 %iv.next, 1
556   br i1 %brcond, label %if.true, label %if.false
558 if.true:
559   br label %backedge
561 if.false:
562   br label %backedge
564 backedge:
565   %loopcond = icmp slt i64 %iv, 200
566   br i1 %loopcond, label %loop, label %exit
568 exit:
569   ret void
572 ; check that we can prove that a recurrency is greater than another recurrency
573 ; in the same loop, with the same step, and with smaller starting value.
574 define void @test12(i64* %inc_ptr) {
575 ; CHECK-LABEL: @test12(
576 ; CHECK-NEXT:  entry:
577 ; CHECK-NEXT:    [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], align 8, !range [[RNG0]]
578 ; CHECK-NEXT:    br label [[LOOP:%.*]]
579 ; CHECK:       loop:
580 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
581 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
582 ; CHECK-NEXT:    br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
583 ; CHECK:       if.true:
584 ; CHECK-NEXT:    br label [[BACKEDGE]]
585 ; CHECK:       if.false:
586 ; CHECK-NEXT:    br label [[BACKEDGE]]
587 ; CHECK:       backedge:
588 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], 201
589 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
590 ; CHECK:       exit:
591 ; CHECK-NEXT:    ret void
593 entry:
594   %inc = load i64, i64* %inc_ptr, !range !0
595   %inc.minus.1 = sub i64 %inc, 1
596   br label %loop
598 loop:
599   %iv = phi i64 [ %inc, %entry ], [ %iv.next, %backedge ]
600   %iv.minus.1 = phi i64 [ %inc.minus.1, %entry ], [ %iv.minus.1.next, %backedge ]
601   %iv.next = add i64 %iv, 1
602   %iv.minus.1.next = add i64 %iv.minus.1, 1
603   %brcond = icmp sgt i64 %iv.next, %iv.minus.1.next
604   br i1 %brcond, label %if.true, label %if.false
606 if.true:
607   br label %backedge
609 if.false:
610   br label %backedge
612 backedge:
613   %loopcond = icmp slt i64 %iv, 200
614   br i1 %loopcond, label %loop, label %exit
616 exit:
617   ret void
620 !0 = !{i64 0, i64 100}
621 !1 = !{i64 -1, i64 100}
623 declare void @foo()