1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -indvars -S < %s | FileCheck %s
3
4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
5
6@X = external global [0 x double]
7
8; Indvars should be able to simplify simple comparisons involving
9; induction variables.
10
11define void @foo(i64 %n, i32* nocapture %p) nounwind {
12; CHECK-LABEL: @foo(
13; CHECK-NEXT:  entry:
14; CHECK-NEXT:    [[CMP9:%.*]] = icmp sgt i64 [[N:%.*]], 0
15; CHECK-NEXT:    br i1 [[CMP9]], label [[PRE:%.*]], label [[RETURN:%.*]]
16; CHECK:       pre:
17; CHECK-NEXT:    [[T3:%.*]] = load i32, i32* [[P:%.*]], align 4
18; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp ne i32 [[T3]], 0
19; CHECK-NEXT:    br label [[LOOP:%.*]]
20; CHECK:       loop:
21; CHECK-NEXT:    [[I:%.*]] = phi i64 [ 0, [[PRE]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
22; CHECK-NEXT:    [[COND:%.*]] = and i1 [[TOBOOL_NOT]], true
23; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[FOR_INC]]
24; CHECK:       if.then:
25; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr [0 x double], [0 x double]* @X, i64 0, i64 [[I]]
26; CHECK-NEXT:    store double 3.200000e+00, double* [[ARRAYIDX]], align 8
27; CHECK-NEXT:    br label [[FOR_INC]]
28; CHECK:       for.inc:
29; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I]], 1
30; CHECK-NEXT:    [[EXITCOND1:%.*]] = icmp eq i64 [[INC]], [[N]]
31; CHECK-NEXT:    br i1 [[EXITCOND1]], label [[RETURN_LOOPEXIT:%.*]], label [[LOOP]]
32; CHECK:       return.loopexit:
33; CHECK-NEXT:    br label [[RETURN]]
34; CHECK:       return:
35; CHECK-NEXT:    ret void
36;
37entry:
38  %cmp9 = icmp sgt i64 %n, 0
39  br i1 %cmp9, label %pre, label %return
40
41pre:
42  %t3 = load i32, i32* %p
43  %tobool.not = icmp ne i32 %t3, 0
44  br label %loop
45
46loop:
47  %i = phi i64 [ 0, %pre ], [ %inc, %for.inc ]
48  %cmp6 = icmp slt i64 %i, %n
49  %cond = and i1 %tobool.not, %cmp6
50  br i1 %cond, label %if.then, label %for.inc
51
52if.then:
53  %arrayidx = getelementptr [0 x double], [0 x double]* @X, i64 0, i64 %i
54  store double 3.200000e+00, double* %arrayidx
55  br label %for.inc
56
57for.inc:
58  %inc = add nsw i64 %i, 1
59  %exitcond = icmp sge i64 %inc, %n
60  br i1 %exitcond, label %return, label %loop
61
62return:
63  ret void
64}
65
66; Don't eliminate an icmp that's contributing to the loop exit test though.
67
68define i32 @_ZNK4llvm5APInt3ultERKS0_(i32 %tmp2.i1, i64** %tmp65, i64** %tmp73, i64** %tmp82, i64** %tmp90) {
69; CHECK-LABEL: @_ZNK4llvm5APInt3ultERKS0_(
70; CHECK-NEXT:  entry:
71; CHECK-NEXT:    br label [[BB18:%.*]]
72; CHECK:       bb13:
73; CHECK-NEXT:    [[TMP66:%.*]] = load i64*, i64** [[TMP65:%.*]], align 4
74; CHECK-NEXT:    [[TMP68:%.*]] = getelementptr inbounds i64, i64* [[TMP66]], i32 [[I:%.*]]
75; CHECK-NEXT:    [[TMP69:%.*]] = load i64, i64* [[TMP68]], align 4
76; CHECK-NEXT:    [[TMP74:%.*]] = load i64*, i64** [[TMP73:%.*]], align 4
77; CHECK-NEXT:    [[TMP76:%.*]] = getelementptr inbounds i64, i64* [[TMP74]], i32 [[I]]
78; CHECK-NEXT:    [[TMP77:%.*]] = load i64, i64* [[TMP76]], align 4
79; CHECK-NEXT:    [[TMP78:%.*]] = icmp ugt i64 [[TMP69]], [[TMP77]]
80; CHECK-NEXT:    br i1 [[TMP78]], label [[BB20_LOOPEXIT:%.*]], label [[BB15:%.*]]
81; CHECK:       bb15:
82; CHECK-NEXT:    [[TMP83:%.*]] = load i64*, i64** [[TMP82:%.*]], align 4
83; CHECK-NEXT:    [[TMP85:%.*]] = getelementptr inbounds i64, i64* [[TMP83]], i32 [[I]]
84; CHECK-NEXT:    [[TMP86:%.*]] = load i64, i64* [[TMP85]], align 4
85; CHECK-NEXT:    [[TMP91:%.*]] = load i64*, i64** [[TMP90:%.*]], align 4
86; CHECK-NEXT:    [[TMP93:%.*]] = getelementptr inbounds i64, i64* [[TMP91]], i32 [[I]]
87; CHECK-NEXT:    [[TMP94:%.*]] = load i64, i64* [[TMP93]], align 4
88; CHECK-NEXT:    [[TMP95:%.*]] = icmp ult i64 [[TMP86]], [[TMP94]]
89; CHECK-NEXT:    br i1 [[TMP95]], label [[BB20_LOOPEXIT]], label [[BB17:%.*]]
90; CHECK:       bb17:
91; CHECK-NEXT:    [[TMP97:%.*]] = add nsw i32 [[I]], -1
92; CHECK-NEXT:    br label [[BB18]]
93; CHECK:       bb18:
94; CHECK-NEXT:    [[I]] = phi i32 [ [[TMP2_I1:%.*]], [[ENTRY:%.*]] ], [ [[TMP97]], [[BB17]] ]
95; CHECK-NEXT:    [[TMP99:%.*]] = icmp sgt i32 [[I]], -1
96; CHECK-NEXT:    br i1 [[TMP99]], label [[BB13:%.*]], label [[BB20_LOOPEXIT]]
97; CHECK:       bb20.loopexit:
98; CHECK-NEXT:    [[TMP_0_PH:%.*]] = phi i32 [ 0, [[BB18]] ], [ 1, [[BB15]] ], [ 0, [[BB13]] ]
99; CHECK-NEXT:    ret i32 [[TMP_0_PH]]
100;
101entry:
102  br label %bb18
103
104bb13:
105  %tmp66 = load i64*, i64** %tmp65, align 4
106  %tmp68 = getelementptr inbounds i64, i64* %tmp66, i32 %i
107  %tmp69 = load i64, i64* %tmp68, align 4
108  %tmp74 = load i64*, i64** %tmp73, align 4
109  %tmp76 = getelementptr inbounds i64, i64* %tmp74, i32 %i
110  %tmp77 = load i64, i64* %tmp76, align 4
111  %tmp78 = icmp ugt i64 %tmp69, %tmp77
112  br i1 %tmp78, label %bb20.loopexit, label %bb15
113
114bb15:
115  %tmp83 = load i64*, i64** %tmp82, align 4
116  %tmp85 = getelementptr inbounds i64, i64* %tmp83, i32 %i
117  %tmp86 = load i64, i64* %tmp85, align 4
118  %tmp91 = load i64*, i64** %tmp90, align 4
119  %tmp93 = getelementptr inbounds i64, i64* %tmp91, i32 %i
120  %tmp94 = load i64, i64* %tmp93, align 4
121  %tmp95 = icmp ult i64 %tmp86, %tmp94
122  br i1 %tmp95, label %bb20.loopexit, label %bb17
123
124bb17:
125  %tmp97 = add nsw i32 %i, -1
126  br label %bb18
127
128bb18:
129  %i = phi i32 [ %tmp2.i1, %entry ], [ %tmp97, %bb17 ]
130  %tmp99 = icmp sgt i32 %i, -1
131  br i1 %tmp99, label %bb13, label %bb20.loopexit
132
133bb20.loopexit:
134  %tmp.0.ph = phi i32 [ 0, %bb18 ], [ 1, %bb15 ], [ 0, %bb13 ]
135  ret i32 %tmp.0.ph
136}
137
138; Indvars should eliminate the icmp here.
139
140
141define void @func_10() nounwind {
142; CHECK-LABEL: @func_10(
143; CHECK-NEXT:  entry:
144; CHECK-NEXT:    br label [[LOOP:%.*]]
145; CHECK:       loop:
146; CHECK-NEXT:    store i64 0, i64* null, align 8
147; CHECK-NEXT:    br i1 false, label [[LOOP]], label [[RETURN:%.*]]
148; CHECK:       return:
149; CHECK-NEXT:    ret void
150;
151entry:
152  br label %loop
153
154loop:
155  %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]
156  %t0 = icmp slt i32 %i, 0
157  %t1 = zext i1 %t0 to i32
158  %t2 = add i32 %t1, %i
159  %u3 = zext i32 %t2 to i64
160  store i64 %u3, i64* null
161  %i.next = add i32 %i, 1
162  br i1 undef, label %loop, label %return
163
164return:
165  ret void
166}
167
168; PR14432
169; Indvars should not turn the second loop into an infinite one.
170
171
172define i32 @func_11() nounwind uwtable {
173; CHECK-LABEL: @func_11(
174; CHECK-NEXT:  entry:
175; CHECK-NEXT:    br label [[FORCOND:%.*]]
176; CHECK:       forcond:
177; CHECK-NEXT:    br i1 false, label [[NOASSERT:%.*]], label [[FORCOND38_PREHEADER:%.*]]
178; CHECK:       forcond38.preheader:
179; CHECK-NEXT:    br label [[FORCOND38:%.*]]
180; CHECK:       noassert:
181; CHECK-NEXT:    br i1 true, label [[FORCOND]], label [[ASSERT33:%.*]]
182; CHECK:       assert33:
183; CHECK-NEXT:    tail call void @llvm.trap()
184; CHECK-NEXT:    unreachable
185; CHECK:       forcond38:
186; CHECK-NEXT:    br i1 false, label [[NOASSERT68:%.*]], label [[UNROLLEDEND:%.*]]
187; CHECK:       noassert68:
188; CHECK-NEXT:    br i1 true, label [[FORCOND38]], label [[ASSERT77:%.*]]
189; CHECK:       assert77:
190; CHECK-NEXT:    tail call void @llvm.trap()
191; CHECK-NEXT:    unreachable
192; CHECK:       unrolledend:
193; CHECK-NEXT:    ret i32 0
194;
195entry:
196  br label %forcond
197
198forcond:                                          ; preds = %noassert, %entry
199  %__key6.0 = phi i32 [ 2, %entry ], [ %tmp37, %noassert ]
200  %tmp5 = icmp slt i32 %__key6.0, 10
201  br i1 %tmp5, label %noassert, label %forcond38.preheader
202
203forcond38.preheader:                              ; preds = %forcond
204  br label %forcond38
205
206noassert:                                         ; preds = %forbody
207  %tmp13 = sdiv i32 -32768, %__key6.0
208  %tmp2936 = shl i32 %tmp13, 24
209  %sext23 = shl i32 %tmp13, 24
210  %tmp32 = icmp eq i32 %tmp2936, %sext23
211  %tmp37 = add i32 %__key6.0, 1
212  br i1 %tmp32, label %forcond, label %assert33
213
214assert33:                                         ; preds = %noassert
215  tail call void @llvm.trap()
216  unreachable
217
218forcond38:                                        ; preds = %noassert68, %forcond38.preheader
219  %__key8.0 = phi i32 [ %tmp81, %noassert68 ], [ 2, %forcond38.preheader ]
220  %tmp46 = icmp slt i32 %__key8.0, 10
221  br i1 %tmp46, label %noassert68, label %unrolledend
222
223noassert68:                                       ; preds = %forbody39
224  %tmp57 = sdiv i32 -32768, %__key8.0
225  %sext34 = shl i32 %tmp57, 16
226  %sext21 = shl i32 %tmp57, 16
227  %tmp76 = icmp eq i32 %sext34, %sext21
228  %tmp81 = add i32 %__key8.0, 1
229  br i1 %tmp76, label %forcond38, label %assert77
230
231assert77:                                         ; preds = %noassert68
232  tail call void @llvm.trap()
233  unreachable
234
235unrolledend:                                      ; preds = %forcond38
236  ret i32 0
237}
238
239define i32 @func_11_flipped() nounwind uwtable {
240; CHECK-LABEL: @func_11_flipped(
241; CHECK-NEXT:  entry:
242; CHECK-NEXT:    br label [[FORCOND:%.*]]
243; CHECK:       forcond:
244; CHECK-NEXT:    br i1 true, label [[FORCOND38_PREHEADER:%.*]], label [[NOASSERT:%.*]]
245; CHECK:       forcond38.preheader:
246; CHECK-NEXT:    br label [[FORCOND38:%.*]]
247; CHECK:       noassert:
248; CHECK-NEXT:    br i1 true, label [[FORCOND]], label [[ASSERT33:%.*]]
249; CHECK:       assert33:
250; CHECK-NEXT:    tail call void @llvm.trap()
251; CHECK-NEXT:    unreachable
252; CHECK:       forcond38:
253; CHECK-NEXT:    br i1 false, label [[NOASSERT68:%.*]], label [[UNROLLEDEND:%.*]]
254; CHECK:       noassert68:
255; CHECK-NEXT:    br i1 true, label [[FORCOND38]], label [[ASSERT77:%.*]]
256; CHECK:       assert77:
257; CHECK-NEXT:    tail call void @llvm.trap()
258; CHECK-NEXT:    unreachable
259; CHECK:       unrolledend:
260; CHECK-NEXT:    ret i32 0
261;
262entry:
263  br label %forcond
264
265forcond:                                          ; preds = %noassert, %entry
266  %__key6.0 = phi i32 [ 2, %entry ], [ %tmp37, %noassert ]
267  %tmp5 = icmp sge i32 %__key6.0, 10
268  br i1 %tmp5, label %forcond38.preheader, label %noassert
269
270forcond38.preheader:                              ; preds = %forcond
271  br label %forcond38
272
273noassert:                                         ; preds = %forbody
274  %tmp13 = sdiv i32 -32768, %__key6.0
275  %tmp2936 = shl i32 %tmp13, 24
276  %sext23 = shl i32 %tmp13, 24
277  %tmp32 = icmp eq i32 %tmp2936, %sext23
278  %tmp37 = add i32 %__key6.0, 1
279  br i1 %tmp32, label %forcond, label %assert33
280
281assert33:                                         ; preds = %noassert
282  tail call void @llvm.trap()
283  unreachable
284
285forcond38:                                        ; preds = %noassert68, %forcond38.preheader
286  %__key8.0 = phi i32 [ %tmp81, %noassert68 ], [ 2, %forcond38.preheader ]
287  %tmp46 = icmp slt i32 %__key8.0, 10
288  br i1 %tmp46, label %noassert68, label %unrolledend
289
290noassert68:                                       ; preds = %forbody39
291  %tmp57 = sdiv i32 -32768, %__key8.0
292  %sext34 = shl i32 %tmp57, 16
293  %sext21 = shl i32 %tmp57, 16
294  %tmp76 = icmp eq i32 %sext34, %sext21
295  %tmp81 = add i32 %__key8.0, 1
296  br i1 %tmp76, label %forcond38, label %assert77
297
298assert77:                                         ; preds = %noassert68
299  tail call void @llvm.trap()
300  unreachable
301
302unrolledend:                                      ; preds = %forcond38
303  ret i32 0
304}
305
306declare void @llvm.trap() noreturn nounwind
307
308; In this case the second loop only has a single iteration, fold the header away
309define i32 @func_12() nounwind uwtable {
310; CHECK-LABEL: @func_12(
311; CHECK-NEXT:  entry:
312; CHECK-NEXT:    br label [[FORCOND:%.*]]
313; CHECK:       forcond:
314; CHECK-NEXT:    br i1 false, label [[NOASSERT:%.*]], label [[FORCOND38_PREHEADER:%.*]]
315; CHECK:       forcond38.preheader:
316; CHECK-NEXT:    br label [[FORCOND38:%.*]]
317; CHECK:       noassert:
318; CHECK-NEXT:    br i1 true, label [[FORCOND]], label [[ASSERT33:%.*]]
319; CHECK:       assert33:
320; CHECK-NEXT:    tail call void @llvm.trap()
321; CHECK-NEXT:    unreachable
322; CHECK:       forcond38:
323; CHECK-NEXT:    br i1 true, label [[NOASSERT68:%.*]], label [[UNROLLEDEND:%.*]]
324; CHECK:       noassert68:
325; CHECK-NEXT:    br i1 false, label [[FORCOND38]], label [[ASSERT77:%.*]]
326; CHECK:       assert77:
327; CHECK-NEXT:    tail call void @llvm.trap()
328; CHECK-NEXT:    unreachable
329; CHECK:       unrolledend:
330; CHECK-NEXT:    ret i32 0
331;
332entry:
333  br label %forcond
334
335forcond:                                          ; preds = %noassert, %entry
336  %__key6.0 = phi i32 [ 2, %entry ], [ %tmp37, %noassert ]
337  %tmp5 = icmp slt i32 %__key6.0, 10
338  br i1 %tmp5, label %noassert, label %forcond38.preheader
339
340forcond38.preheader:                              ; preds = %forcond
341  br label %forcond38
342
343noassert:                                         ; preds = %forbody
344  %tmp13 = sdiv i32 -32768, %__key6.0
345  %tmp2936 = shl i32 %tmp13, 24
346  %sext23 = shl i32 %tmp13, 24
347  %tmp32 = icmp eq i32 %tmp2936, %sext23
348  %tmp37 = add i32 %__key6.0, 1
349  br i1 %tmp32, label %forcond, label %assert33
350
351assert33:                                         ; preds = %noassert
352  tail call void @llvm.trap()
353  unreachable
354
355forcond38:                                        ; preds = %noassert68, %forcond38.preheader
356  %__key8.0 = phi i32 [ %tmp81, %noassert68 ], [ 2, %forcond38.preheader ]
357  %tmp46 = icmp slt i32 %__key8.0, 10
358  br i1 %tmp46, label %noassert68, label %unrolledend
359
360noassert68:                                       ; preds = %forbody39
361  %tmp57 = sdiv i32 -32768, %__key8.0
362  %sext34 = shl i32 %tmp57, 16
363  %sext21 = shl i32 %tmp57, 16
364  %tmp76 = icmp ne i32 %sext34, %sext21
365  %tmp81 = add i32 %__key8.0, 1
366  br i1 %tmp76, label %forcond38, label %assert77
367
368assert77:                                         ; preds = %noassert68
369  tail call void @llvm.trap()
370  unreachable
371
372unrolledend:                                      ; preds = %forcond38
373  ret i32 0
374}
375
376declare void @side_effect()
377
378define void @func_13(i32* %len.ptr) {
379; CHECK-LABEL: @func_13(
380; CHECK-NEXT:  entry:
381; CHECK-NEXT:    [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4, !range [[RNG0:![0-9]+]]
382; CHECK-NEXT:    [[LEN_IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0
383; CHECK-NEXT:    br i1 [[LEN_IS_ZERO]], label [[LEAVE:%.*]], label [[LOOP_PREHEADER:%.*]]
384; CHECK:       loop.preheader:
385; CHECK-NEXT:    br label [[LOOP:%.*]]
386; CHECK:       loop:
387; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
388; CHECK-NEXT:    call void @side_effect()
389; CHECK-NEXT:    [[IV_INC]] = add nuw nsw i32 [[IV]], 1
390; CHECK-NEXT:    br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
391; CHECK:       be:
392; CHECK-NEXT:    call void @side_effect()
393; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[LEN]]
394; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
395; CHECK:       leave.loopexit:
396; CHECK-NEXT:    br label [[LEAVE]]
397; CHECK:       leave:
398; CHECK-NEXT:    ret void
399;
400entry:
401  %len = load i32, i32* %len.ptr, !range !0
402  %len.sub.1 = add i32 %len, -1
403  %len.is.zero = icmp eq i32 %len, 0
404  br i1 %len.is.zero, label %leave, label %loop
405
406loop:
407  %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
408  call void @side_effect()
409  %iv.inc = add i32 %iv, 1
410  %iv.cmp = icmp ult i32 %iv, %len
411  br i1 %iv.cmp, label %be, label %leave
412
413be:
414  call void @side_effect()
415  %be.cond = icmp ult i32 %iv, %len.sub.1
416  br i1 %be.cond, label %loop, label %leave
417
418leave:
419  ret void
420}
421
422define void @func_14(i32* %len.ptr) {
423; CHECK-LABEL: @func_14(
424; CHECK-NEXT:  entry:
425; CHECK-NEXT:    [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4, !range [[RNG0]]
426; CHECK-NEXT:    [[LEN_IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0
427; CHECK-NEXT:    [[LEN_IS_INT_MIN:%.*]] = icmp eq i32 [[LEN]], -2147483648
428; CHECK-NEXT:    [[NO_ENTRY:%.*]] = or i1 [[LEN_IS_ZERO]], [[LEN_IS_INT_MIN]]
429; CHECK-NEXT:    br i1 [[NO_ENTRY]], label [[LEAVE:%.*]], label [[LOOP_PREHEADER:%.*]]
430; CHECK:       loop.preheader:
431; CHECK-NEXT:    br label [[LOOP:%.*]]
432; CHECK:       loop:
433; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
434; CHECK-NEXT:    call void @side_effect()
435; CHECK-NEXT:    [[IV_INC]] = add nuw nsw i32 [[IV]], 1
436; CHECK-NEXT:    br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
437; CHECK:       be:
438; CHECK-NEXT:    call void @side_effect()
439; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[LEN]]
440; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
441; CHECK:       leave.loopexit:
442; CHECK-NEXT:    br label [[LEAVE]]
443; CHECK:       leave:
444; CHECK-NEXT:    ret void
445;
446entry:
447  %len = load i32, i32* %len.ptr, !range !0
448  %len.sub.1 = add i32 %len, -1
449  %len.is.zero = icmp eq i32 %len, 0
450  %len.is.int_min = icmp eq i32 %len, 2147483648
451  %no.entry = or i1 %len.is.zero, %len.is.int_min
452  br i1 %no.entry, label %leave, label %loop
453
454loop:
455  %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
456  call void @side_effect()
457  %iv.inc = add i32 %iv, 1
458  %iv.cmp = icmp slt i32 %iv, %len
459  br i1 %iv.cmp, label %be, label %leave
460
461be:
462  call void @side_effect()
463  %be.cond = icmp slt i32 %iv, %len.sub.1
464  br i1 %be.cond, label %loop, label %leave
465
466leave:
467  ret void
468}
469
470define void @func_15(i32* %len.ptr) {
471; CHECK-LABEL: @func_15(
472; CHECK-NEXT:  entry:
473; CHECK-NEXT:    [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4, !range [[RNG0]]
474; CHECK-NEXT:    [[LEN_ADD_1:%.*]] = add i32 [[LEN]], 1
475; CHECK-NEXT:    [[LEN_ADD_1_IS_ZERO:%.*]] = icmp eq i32 [[LEN_ADD_1]], 0
476; CHECK-NEXT:    br i1 [[LEN_ADD_1_IS_ZERO]], label [[LEAVE:%.*]], label [[LOOP_PREHEADER:%.*]]
477; CHECK:       loop.preheader:
478; CHECK-NEXT:    br label [[LOOP:%.*]]
479; CHECK:       loop:
480; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
481; CHECK-NEXT:    call void @side_effect()
482; CHECK-NEXT:    [[IV_INC]] = add nuw nsw i32 [[IV]], 1
483; CHECK-NEXT:    br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
484; CHECK:       be:
485; CHECK-NEXT:    call void @side_effect()
486; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[LEN_ADD_1]]
487; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
488; CHECK:       leave.loopexit:
489; CHECK-NEXT:    br label [[LEAVE]]
490; CHECK:       leave:
491; CHECK-NEXT:    ret void
492;
493entry:
494  %len = load i32, i32* %len.ptr, !range !0
495  %len.add.1 = add i32 %len, 1
496  %len.add.1.is.zero = icmp eq i32 %len.add.1, 0
497  br i1 %len.add.1.is.zero, label %leave, label %loop
498
499loop:
500  %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
501  call void @side_effect()
502  %iv.inc = add i32 %iv, 1
503  %iv.cmp = icmp ult i32 %iv, %len.add.1
504  br i1 %iv.cmp, label %be, label %leave
505
506be:
507  call void @side_effect()
508  %be.cond = icmp ult i32 %iv, %len
509  br i1 %be.cond, label %loop, label %leave
510
511leave:
512  ret void
513}
514
515define void @func_16(i32* %len.ptr) {
516; CHECK-LABEL: @func_16(
517; CHECK-NEXT:  entry:
518; CHECK-NEXT:    [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4, !range [[RNG0]]
519; CHECK-NEXT:    [[LEN_ADD_5:%.*]] = add i32 [[LEN]], 5
520; CHECK-NEXT:    [[ENTRY_COND_0:%.*]] = icmp slt i32 [[LEN]], 2147483643
521; CHECK-NEXT:    [[ENTRY_COND_1:%.*]] = icmp slt i32 4, [[LEN_ADD_5]]
522; CHECK-NEXT:    [[ENTRY_COND:%.*]] = and i1 [[ENTRY_COND_0]], [[ENTRY_COND_1]]
523; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
524; CHECK:       loop.preheader:
525; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[LEN]], 1
526; CHECK-NEXT:    br label [[LOOP:%.*]]
527; CHECK:       loop:
528; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
529; CHECK-NEXT:    call void @side_effect()
530; CHECK-NEXT:    [[IV_INC]] = add nuw nsw i32 [[IV]], 1
531; CHECK-NEXT:    br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
532; CHECK:       be:
533; CHECK-NEXT:    call void @side_effect()
534; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[TMP0]]
535; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
536; CHECK:       leave.loopexit:
537; CHECK-NEXT:    br label [[LEAVE]]
538; CHECK:       leave:
539; CHECK-NEXT:    ret void
540;
541entry:
542  %len = load i32, i32* %len.ptr, !range !0
543  %len.add.5 = add i32 %len, 5
544  %entry.cond.0 = icmp slt i32 %len, 2147483643
545  %entry.cond.1 = icmp slt i32 4, %len.add.5
546  %entry.cond = and i1 %entry.cond.0, %entry.cond.1
547  br i1 %entry.cond, label %loop, label %leave
548
549loop:
550  %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
551  call void @side_effect()
552  %iv.inc = add i32 %iv, 1
553  %iv.add.4 = add i32 %iv, 4
554  %iv.cmp = icmp slt i32 %iv.add.4, %len.add.5
555  br i1 %iv.cmp, label %be, label %leave
556
557be:
558  call void @side_effect()
559  %be.cond = icmp slt i32 %iv, %len
560  br i1 %be.cond, label %loop, label %leave
561
562leave:
563  ret void
564}
565
566define void @func_17(i32* %len.ptr) {
567; CHECK-LABEL: @func_17(
568; CHECK-NEXT:  entry:
569; CHECK-NEXT:    [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4
570; CHECK-NEXT:    [[LEN_ADD_5:%.*]] = add i32 [[LEN]], -5
571; CHECK-NEXT:    [[ENTRY_COND_0:%.*]] = icmp slt i32 [[LEN]], -2147483643
572; CHECK-NEXT:    [[ENTRY_COND_1:%.*]] = icmp slt i32 -6, [[LEN_ADD_5]]
573; CHECK-NEXT:    [[ENTRY_COND:%.*]] = and i1 [[ENTRY_COND_0]], [[ENTRY_COND_1]]
574; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
575; CHECK:       loop.preheader:
576; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[LEN]], i32 0)
577; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[SMAX]], -5
578; CHECK-NEXT:    br label [[LOOP:%.*]]
579; CHECK:       loop:
580; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ -6, [[LOOP_PREHEADER]] ]
581; CHECK-NEXT:    call void @side_effect()
582; CHECK-NEXT:    [[IV_INC]] = add nsw i32 [[IV]], 1
583; CHECK-NEXT:    br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
584; CHECK:       be:
585; CHECK-NEXT:    call void @side_effect()
586; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[TMP0]]
587; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
588; CHECK:       leave.loopexit:
589; CHECK-NEXT:    br label [[LEAVE]]
590; CHECK:       leave:
591; CHECK-NEXT:    ret void
592;
593entry:
594  %len = load i32, i32* %len.ptr
595  %len.add.5 = add i32 %len, -5
596  %entry.cond.0 = icmp slt i32 %len, 2147483653 ;; 2147483653 == INT_MIN - (-5)
597  %entry.cond.1 = icmp slt i32 -6, %len.add.5
598  %entry.cond = and i1 %entry.cond.0, %entry.cond.1
599  br i1 %entry.cond, label %loop, label %leave
600
601loop:
602  %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.inc, %be ]
603  %iv = phi i32 [ -6, %entry ], [ %iv.inc, %be ]
604  call void @side_effect()
605  %iv.inc = add i32 %iv, 1
606  %iv.2.inc = add i32 %iv.2, 1
607  %iv.cmp = icmp slt i32 %iv, %len.add.5
608
609; Deduces {-5,+,1} s< (-5 + %len) from {0,+,1} < %len
610; since %len s< INT_MIN - (-5) from the entry condition
611  br i1 %iv.cmp, label %be, label %leave
612
613be:
614  call void @side_effect()
615  %be.cond = icmp slt i32 %iv.2, %len
616  br i1 %be.cond, label %loop, label %leave
617
618leave:
619  ret void
620}
621
622define i1 @func_18(i16* %tmp20, i32* %len.addr) {
623; CHECK-LABEL: @func_18(
624; CHECK-NEXT:  entry:
625; CHECK-NEXT:    [[LEN:%.*]] = load i32, i32* [[LEN_ADDR:%.*]], align 4, !range [[RNG0]]
626; CHECK-NEXT:    [[TMP18:%.*]] = icmp eq i32 [[LEN]], 0
627; CHECK-NEXT:    br i1 [[TMP18]], label [[BB2:%.*]], label [[BB0_PREHEADER:%.*]]
628; CHECK:       bb0.preheader:
629; CHECK-NEXT:    br label [[BB0:%.*]]
630; CHECK:       bb0:
631; CHECK-NEXT:    [[VAR_0_IN:%.*]] = phi i32 [ [[VAR_0:%.*]], [[BB1:%.*]] ], [ [[LEN]], [[BB0_PREHEADER]] ]
632; CHECK-NEXT:    [[VAR_1:%.*]] = phi i32 [ [[TMP30:%.*]], [[BB1]] ], [ 0, [[BB0_PREHEADER]] ]
633; CHECK-NEXT:    [[VAR_0]] = add nsw i32 [[VAR_0_IN]], -1
634; CHECK-NEXT:    br i1 true, label [[STAY:%.*]], label [[BB2_LOOPEXIT:%.*]]
635; CHECK:       stay:
636; CHECK-NEXT:    [[TMP25:%.*]] = getelementptr inbounds i16, i16* [[TMP20:%.*]], i32 [[VAR_1]]
637; CHECK-NEXT:    [[TMP26:%.*]] = load i16, i16* [[TMP25]], align 2
638; CHECK-NEXT:    [[TMP29:%.*]] = icmp eq i16 [[TMP26]], 0
639; CHECK-NEXT:    br i1 [[TMP29]], label [[BB1]], label [[BB2_LOOPEXIT]]
640; CHECK:       bb1:
641; CHECK-NEXT:    [[TMP30]] = add nuw i32 [[VAR_1]], 1
642; CHECK-NEXT:    [[TMP31:%.*]] = icmp eq i32 [[VAR_0]], 0
643; CHECK-NEXT:    br i1 [[TMP31]], label [[BB3:%.*]], label [[BB0]]
644; CHECK:       bb2.loopexit:
645; CHECK-NEXT:    br label [[BB2]]
646; CHECK:       bb2:
647; CHECK-NEXT:    ret i1 false
648; CHECK:       bb3:
649; CHECK-NEXT:    ret i1 true
650;
651entry:
652  %len = load i32, i32* %len.addr, !range !0
653  %tmp18 = icmp eq i32 %len, 0
654  br i1 %tmp18, label %bb2, label %bb0.preheader
655
656bb0.preheader:
657  br label %bb0
658
659bb0:
660  %var_0.in = phi i32 [ %var_0, %bb1 ], [ %len, %bb0.preheader ]
661  %var_1 = phi i32 [ %tmp30, %bb1 ], [ 0, %bb0.preheader ]
662  %var_0 = add nsw i32 %var_0.in, -1
663  %tmp23 = icmp ult i32 %var_1, %len
664  br i1 %tmp23, label %stay, label %bb2
665
666stay:
667  %tmp25 = getelementptr inbounds i16, i16* %tmp20, i32 %var_1
668  %tmp26 = load i16, i16* %tmp25
669  %tmp29 = icmp eq i16 %tmp26, 0
670  br i1 %tmp29, label %bb1, label %bb2
671
672bb1:
673  %tmp30 = add i32 %var_1, 1
674  %tmp31 = icmp eq i32 %var_0, 0
675  br i1 %tmp31, label %bb3, label %bb0
676
677bb2:
678  ret i1 false
679
680bb3:
681  ret i1 true
682}
683
684define void @func_19(i32* %length.ptr) {
685; CHECK-LABEL: @func_19(
686; CHECK-NEXT:  entry:
687; CHECK-NEXT:    [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG0]]
688; CHECK-NEXT:    [[LENGTH_IS_NONZERO:%.*]] = icmp ne i32 [[LENGTH]], 0
689; CHECK-NEXT:    br i1 [[LENGTH_IS_NONZERO]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
690; CHECK:       loop.preheader:
691; CHECK-NEXT:    br label [[LOOP:%.*]]
692; CHECK:       loop:
693; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
694; CHECK-NEXT:    [[IV_INC]] = add nuw nsw i32 [[IV]], 1
695; CHECK-NEXT:    br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
696; CHECK:       be:
697; CHECK-NEXT:    call void @side_effect()
698; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[LENGTH]]
699; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
700; CHECK:       leave.loopexit:
701; CHECK-NEXT:    br label [[LEAVE]]
702; CHECK:       leave:
703; CHECK-NEXT:    ret void
704;
705entry:
706  %length = load i32, i32* %length.ptr, !range !0
707  %length.is.nonzero = icmp ne i32 %length, 0
708  br i1 %length.is.nonzero, label %loop, label %leave
709
710loop:
711  %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
712  %iv.inc = add i32 %iv, 1
713  %range.check = icmp ult i32 %iv, %length
714  br i1 %range.check, label %be, label %leave
715
716be:
717  call void @side_effect()
718  %be.cond = icmp slt i32 %iv.inc, %length
719  br i1 %be.cond, label %loop, label %leave
720
721leave:
722  ret void
723}
724
725; Like @func_19, but %length is no longer provably positive, so
726; %range.check cannot be proved to be always true.
727define void @func_20(i32* %length.ptr) {
728; CHECK-LABEL: @func_20(
729; CHECK-NEXT:  entry:
730; CHECK-NEXT:    [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4
731; CHECK-NEXT:    [[LENGTH_IS_NONZERO:%.*]] = icmp ne i32 [[LENGTH]], 0
732; CHECK-NEXT:    br i1 [[LENGTH_IS_NONZERO]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
733; CHECK:       loop.preheader:
734; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[LENGTH]], i32 1)
735; CHECK-NEXT:    br label [[LOOP:%.*]]
736; CHECK:       loop:
737; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
738; CHECK-NEXT:    [[IV_INC]] = add nuw nsw i32 [[IV]], 1
739; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV]], [[LENGTH]]
740; CHECK-NEXT:    br i1 [[EXITCOND]], label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
741; CHECK:       be:
742; CHECK-NEXT:    call void @side_effect()
743; CHECK-NEXT:    [[EXITCOND1:%.*]] = icmp ne i32 [[IV_INC]], [[SMAX]]
744; CHECK-NEXT:    br i1 [[EXITCOND1]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
745; CHECK:       leave.loopexit:
746; CHECK-NEXT:    br label [[LEAVE]]
747; CHECK:       leave:
748; CHECK-NEXT:    ret void
749;
750entry:
751  %length = load i32, i32* %length.ptr
752  %length.is.nonzero = icmp ne i32 %length, 0
753  br i1 %length.is.nonzero, label %loop, label %leave
754
755loop:
756  %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
757  %iv.inc = add i32 %iv, 1
758  %range.check = icmp ult i32 %iv, %length
759  br i1 %range.check, label %be, label %leave
760
761be:
762  call void @side_effect()
763  %be.cond = icmp slt i32 %iv.inc, %length
764  br i1 %be.cond, label %loop, label %leave
765
766leave:
767  ret void
768}
769
770; This checks that the backedge condition, (I + 1) < Length - 1 implies
771; (I + 1) < Length
772define void @func_21(i32* %length.ptr) {
773; CHECK-LABEL: @func_21(
774; CHECK-NEXT:  entry:
775; CHECK-NEXT:    [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG0]]
776; CHECK-NEXT:    [[LIM:%.*]] = sub i32 [[LENGTH]], 1
777; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp sgt i32 [[LENGTH]], 1
778; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
779; CHECK:       loop.preheader:
780; CHECK-NEXT:    br label [[LOOP:%.*]]
781; CHECK:       loop:
782; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
783; CHECK-NEXT:    [[IV_INC]] = add nuw nsw i32 [[IV]], 1
784; CHECK-NEXT:    br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
785; CHECK:       be:
786; CHECK-NEXT:    call void @side_effect()
787; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[LIM]]
788; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
789; CHECK:       leave.loopexit:
790; CHECK-NEXT:    br label [[LEAVE]]
791; CHECK:       leave:
792; CHECK-NEXT:    ret void
793;
794entry:
795  %length = load i32, i32* %length.ptr, !range !0
796  %lim = sub i32 %length, 1
797  %entry.cond = icmp sgt i32 %length, 1
798  br i1 %entry.cond, label %loop, label %leave
799
800loop:
801  %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
802  %iv.inc = add i32 %iv, 1
803  %range.check = icmp slt i32 %iv, %length
804  br i1 %range.check, label %be, label %leave
805
806be:
807  call void @side_effect()
808  %be.cond = icmp slt i32 %iv.inc, %lim
809  br i1 %be.cond, label %loop, label %leave
810
811leave:
812  ret void
813}
814
815; This checks that the backedge condition, (I + 1) < Length - 1 implies
816; (I + 1) < Length
817define void @func_22(i32* %length.ptr) {
818; CHECK-LABEL: @func_22(
819; CHECK-NEXT:  entry:
820; CHECK-NEXT:    [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG0]]
821; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp sgt i32 [[LENGTH]], 1
822; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
823; CHECK:       loop.preheader:
824; CHECK-NEXT:    br label [[LOOP:%.*]]
825; CHECK:       loop:
826; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
827; CHECK-NEXT:    [[IV_INC]] = add nuw nsw i32 [[IV]], 1
828; CHECK-NEXT:    br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
829; CHECK:       be:
830; CHECK-NEXT:    call void @side_effect()
831; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[LENGTH]]
832; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
833; CHECK:       leave.loopexit:
834; CHECK-NEXT:    br label [[LEAVE]]
835; CHECK:       leave:
836; CHECK-NEXT:    ret void
837;
838entry:
839  %length = load i32, i32* %length.ptr, !range !0
840  %lim = sub i32 %length, 1
841  %entry.cond = icmp sgt i32 %length, 1
842  br i1 %entry.cond, label %loop, label %leave
843
844loop:
845  %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
846  %iv.inc = add i32 %iv, 1
847  %range.check = icmp sle i32 %iv, %length
848  br i1 %range.check, label %be, label %leave
849
850be:
851  call void @side_effect()
852  %be.cond = icmp sle i32 %iv.inc, %lim
853  br i1 %be.cond, label %loop, label %leave
854
855leave:
856  ret void
857}
858
859define void @func_23(i32* %length.ptr) {
860; CHECK-LABEL: @func_23(
861; CHECK-NEXT:  entry:
862; CHECK-NEXT:    [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG0]]
863; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp ult i32 4, [[LENGTH]]
864; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
865; CHECK:       loop.preheader:
866; CHECK-NEXT:    br label [[LOOP:%.*]]
867; CHECK:       loop:
868; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 4, [[LOOP_PREHEADER]] ]
869; CHECK-NEXT:    [[IV_INC]] = add nuw nsw i32 [[IV]], 1
870; CHECK-NEXT:    br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
871; CHECK:       be:
872; CHECK-NEXT:    call void @side_effect()
873; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[LENGTH]]
874; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
875; CHECK:       leave.loopexit:
876; CHECK-NEXT:    br label [[LEAVE]]
877; CHECK:       leave:
878; CHECK-NEXT:    ret void
879;
880entry:
881  %length = load i32, i32* %length.ptr, !range !0
882  %entry.cond = icmp ult i32 4, %length
883  br i1 %entry.cond, label %loop, label %leave
884
885loop:
886  %iv = phi i32 [ 4, %entry ], [ %iv.inc, %be ]
887  %iv.inc = add i32 %iv, 1
888  %range.check = icmp slt i32 %iv, %length
889  br i1 %range.check, label %be, label %leave
890
891be:
892  call void @side_effect()
893  %be.cond = icmp slt i32 %iv.inc, %length
894  br i1 %be.cond, label %loop, label %leave
895
896leave:
897  ret void
898}
899
900define void @func_24(i32* %init.ptr) {
901; CHECK-LABEL: @func_24(
902; CHECK-NEXT:  entry:
903; CHECK-NEXT:    [[INIT:%.*]] = load i32, i32* [[INIT_PTR:%.*]], align 4, !range [[RNG0]]
904; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp ugt i32 [[INIT]], 4
905; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
906; CHECK:       loop.preheader:
907; CHECK-NEXT:    br label [[LOOP:%.*]]
908; CHECK:       loop:
909; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_DEC:%.*]], [[BE:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
910; CHECK-NEXT:    [[IV_DEC]] = add nsw i32 [[IV]], -1
911; CHECK-NEXT:    br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
912; CHECK:       be:
913; CHECK-NEXT:    call void @side_effect()
914; CHECK-NEXT:    [[BE_COND:%.*]] = icmp sgt i32 [[IV_DEC]], 4
915; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
916; CHECK:       leave.loopexit:
917; CHECK-NEXT:    br label [[LEAVE]]
918; CHECK:       leave:
919; CHECK-NEXT:    ret void
920;
921entry:
922  %init = load i32, i32* %init.ptr, !range !0
923  %entry.cond = icmp ugt i32 %init, 4
924  br i1 %entry.cond, label %loop, label %leave
925
926loop:
927  %iv = phi i32 [ %init, %entry ], [ %iv.dec, %be ]
928  %iv.dec = add i32 %iv, -1
929  %range.check = icmp sgt i32 %iv, 4
930  br i1 %range.check, label %be, label %leave
931
932be:
933  call void @side_effect()
934  %be.cond = icmp sgt i32 %iv.dec, 4
935  br i1 %be.cond, label %loop, label %leave
936
937leave:
938  ret void
939}
940
941declare i1 @cond_func()
942
943define i32 @func_25(i32 %start) {
944; CHECK-LABEL: @func_25(
945; CHECK-NEXT:  entry:
946; CHECK-NEXT:    br label [[LOOP:%.*]]
947; CHECK:       loop:
948; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
949; CHECK-NEXT:    [[C1:%.*]] = icmp ne i32 [[IV]], 0
950; CHECK-NEXT:    br i1 [[C1]], label [[CHECKED_1:%.*]], label [[FAIL:%.*]]
951; CHECK:       checked.1:
952; CHECK-NEXT:    br i1 true, label [[CHECKED_2:%.*]], label [[FAIL]]
953; CHECK:       checked.2:
954; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[FAIL]]
955; CHECK:       backedge:
956; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 758394
957; CHECK-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond_func()
958; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
959; CHECK:       fail:
960; CHECK-NEXT:    unreachable
961; CHECK:       exit:
962; CHECK-NEXT:    [[IV_LCSSA1:%.*]] = phi i32 [ [[IV]], [[BACKEDGE]] ]
963; CHECK-NEXT:    ret i32 [[IV_LCSSA1]]
964;
965entry:
966  br label %loop
967
968loop:
969  %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
970  %c1 = icmp ne i32 %iv, 0
971  br i1 %c1, label %checked.1, label %fail
972
973checked.1:
974  %c2 = icmp ne i32 %iv, 0
975  br i1 %c2, label %checked.2, label %fail
976
977checked.2:
978  %c3 = icmp ne i32 %iv, 0
979  br i1 %c3, label %backedge, label %fail
980
981backedge:
982  %iv.next = add i32 %iv, 758394
983  %loop.cond = call i1 @cond_func()
984  br i1 %loop.cond, label %loop, label %exit
985
986fail:
987  unreachable
988
989exit:
990  ret i32 %iv
991}
992
993define i32 @func_26(i32 %start) {
994; CHECK-LABEL: @func_26(
995; CHECK-NEXT:  entry:
996; CHECK-NEXT:    br label [[LOOP:%.*]]
997; CHECK:       loop:
998; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
999; CHECK-NEXT:    [[C1:%.*]] = icmp slt i32 [[IV]], 0
1000; CHECK-NEXT:    br i1 [[C1]], label [[CHECKED_1:%.*]], label [[FAIL:%.*]]
1001; CHECK:       checked.1:
1002; CHECK-NEXT:    br i1 true, label [[CHECKED_2:%.*]], label [[FAIL]]
1003; CHECK:       checked.2:
1004; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[FAIL]]
1005; CHECK:       backedge:
1006; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 758394
1007; CHECK-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond_func()
1008; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
1009; CHECK:       fail:
1010; CHECK-NEXT:    unreachable
1011; CHECK:       exit:
1012; CHECK-NEXT:    [[IV_LCSSA1:%.*]] = phi i32 [ [[IV]], [[BACKEDGE]] ]
1013; CHECK-NEXT:    ret i32 [[IV_LCSSA1]]
1014;
1015entry:
1016  br label %loop
1017
1018loop:
1019  %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
1020  %c1 = icmp slt i32 %iv, 0
1021  br i1 %c1, label %checked.1, label %fail
1022
1023checked.1:
1024  %c2 = icmp slt i32 %iv, 1
1025  br i1 %c2, label %checked.2, label %fail
1026
1027checked.2:
1028  %c3 = icmp slt i32 %iv, 2
1029  br i1 %c3, label %backedge, label %fail
1030
1031backedge:
1032  %iv.next = add i32 %iv, 758394
1033  %loop.cond = call i1 @cond_func()
1034  br i1 %loop.cond, label %loop, label %exit
1035
1036fail:
1037  unreachable
1038
1039exit:
1040  ret i32 %iv
1041}
1042
1043define i32 @func_27(i32 %start) {
1044; CHECK-LABEL: @func_27(
1045; CHECK-NEXT:  entry:
1046; CHECK-NEXT:    br label [[LOOP:%.*]]
1047; CHECK:       loop:
1048; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
1049; CHECK-NEXT:    [[C1:%.*]] = icmp slt i32 [[IV]], 2
1050; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[IV]], 1
1051; CHECK-NEXT:    [[C3:%.*]] = icmp slt i32 [[IV]], 0
1052; CHECK-NEXT:    br i1 [[C1]], label [[CHECKED_1:%.*]], label [[FAIL:%.*]]
1053; CHECK:       checked.1:
1054; CHECK-NEXT:    br i1 [[C2]], label [[CHECKED_2:%.*]], label [[FAIL]]
1055; CHECK:       checked.2:
1056; CHECK-NEXT:    br i1 [[C3]], label [[BACKEDGE]], label [[FAIL]]
1057; CHECK:       backedge:
1058; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 758394
1059; CHECK-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond_func()
1060; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
1061; CHECK:       fail:
1062; CHECK-NEXT:    unreachable
1063; CHECK:       exit:
1064; CHECK-NEXT:    [[IV_LCSSA1:%.*]] = phi i32 [ [[IV]], [[BACKEDGE]] ]
1065; CHECK-NEXT:    ret i32 [[IV_LCSSA1]]
1066;
1067entry:
1068  br label %loop
1069
1070loop:
1071  %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
1072  %c1 = icmp slt i32 %iv, 2
1073  %c2 = icmp slt i32 %iv, 1
1074  %c3 = icmp slt i32 %iv, 0
1075  br i1 %c1, label %checked.1, label %fail
1076
1077checked.1:
1078  br i1 %c2, label %checked.2, label %fail
1079
1080checked.2:
1081  br i1 %c3, label %backedge, label %fail
1082
1083backedge:
1084  %iv.next = add i32 %iv, 758394
1085  %loop.cond = call i1 @cond_func()
1086  br i1 %loop.cond, label %loop, label %exit
1087
1088fail:
1089  unreachable
1090
1091exit:
1092  ret i32 %iv
1093}
1094
1095define i32 @func_28(i32 %start) {
1096; CHECK-LABEL: @func_28(
1097; CHECK-NEXT:  entry:
1098; CHECK-NEXT:    br label [[LOOP:%.*]]
1099; CHECK:       loop:
1100; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
1101; CHECK-NEXT:    [[C1:%.*]] = icmp ne i32 [[IV]], 0
1102; CHECK-NEXT:    br i1 [[C1]], label [[CHECKED_1:%.*]], label [[FAIL:%.*]]
1103; CHECK:       checked.1:
1104; CHECK-NEXT:    br i1 true, label [[CHECKED_2:%.*]], label [[FAIL]]
1105; CHECK:       checked.2:
1106; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[FAIL]]
1107; CHECK:       backedge:
1108; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 758394
1109; CHECK-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond_func()
1110; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
1111; CHECK:       fail:
1112; CHECK-NEXT:    unreachable
1113; CHECK:       exit:
1114; CHECK-NEXT:    [[IV_LCSSA1:%.*]] = phi i32 [ [[IV]], [[BACKEDGE]] ]
1115; CHECK-NEXT:    ret i32 [[IV_LCSSA1]]
1116;
1117entry:
1118  br label %loop
1119
1120loop:
1121  %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
1122  %c1 = icmp ne i32 %iv, 0
1123  %c2 = icmp ne i32 %iv, 0
1124  %c3 = icmp ne i32 %iv, 0
1125  br i1 %c1, label %checked.1, label %fail
1126
1127checked.1:
1128  br i1 %c2, label %checked.2, label %fail
1129
1130checked.2:
1131  br i1 %c3, label %backedge, label %fail
1132
1133backedge:
1134  %iv.next = add i32 %iv, 758394
1135  %loop.cond = call i1 @cond_func()
1136  br i1 %loop.cond, label %loop, label %exit
1137
1138fail:
1139  unreachable
1140
1141exit:
1142  ret i32 %iv
1143}
1144
1145!0 = !{i32 0, i32 2147483647}
1146