Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / IndVarSimplify / AArch64 / widen-loop-comp.ll
blob6f659a88da2e2bfae4b3796ab6ef222089ee12db
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=indvars -scalar-evolution-use-expensive-range-sharpening -S | FileCheck %s
4 target triple = "aarch64--linux-gnu"
6 ; Provide legal integer types.
7 target datalayout = "n8:16:32:64"
10 ; Check the loop exit i32 compare instruction and operand are widened to i64
11 ; instead of truncating IV before its use in the i32 compare instruction.
13 @idx = common global i32 0, align 4
14 @e = common global i32 0, align 4
15 @ptr = common global ptr null, align 8
18 define i32 @test1() {
19 ; CHECK-LABEL: @test1(
20 ; CHECK-NEXT:  entry:
21 ; CHECK-NEXT:    store i32 -1, ptr @idx, align 4
22 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @e, align 4
23 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP0]], 0
24 ; CHECK-NEXT:    br i1 [[CMP4]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY_LR_PH:%.*]]
25 ; CHECK:       for.body.lr.ph:
26 ; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr @ptr, align 8
27 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr @e, align 4
28 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP2]], i32 0)
29 ; CHECK-NEXT:    [[TMP3:%.*]] = add nuw i32 [[SMAX]], 1
30 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP3]] to i64
31 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
32 ; CHECK:       for.cond:
33 ; CHECK-NEXT:    [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV:%.*]], 1
34 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
35 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_COND_FOR_END_LOOPEXIT_CRIT_EDGE:%.*]]
36 ; CHECK:       for.body:
37 ; CHECK-NEXT:    [[INDVARS_IV]] = phi i64 [ [[INDVARS_IV_NEXT]], [[FOR_COND:%.*]] ], [ 0, [[FOR_BODY_LR_PH]] ]
38 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[INDVARS_IV]]
39 ; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
40 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[TMP4]], 0
41 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_COND]]
42 ; CHECK:       if.then:
43 ; CHECK-NEXT:    [[I_05_LCSSA_WIDE:%.*]] = phi i64 [ [[INDVARS_IV]], [[FOR_BODY]] ]
44 ; CHECK-NEXT:    [[TMP5:%.*]] = trunc i64 [[I_05_LCSSA_WIDE]] to i32
45 ; CHECK-NEXT:    store i32 [[TMP5]], ptr @idx, align 4
46 ; CHECK-NEXT:    br label [[FOR_END:%.*]]
47 ; CHECK:       for.cond.for.end.loopexit_crit_edge:
48 ; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT]]
49 ; CHECK:       for.end.loopexit:
50 ; CHECK-NEXT:    br label [[FOR_END]]
51 ; CHECK:       for.end:
52 ; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr @idx, align 4
53 ; CHECK-NEXT:    ret i32 [[TMP6]]
55 entry:
56   store i32 -1, ptr @idx, align 4
57   %0 = load i32, ptr @e, align 4
58   %cmp4 = icmp slt i32 %0, 0
59   br i1 %cmp4, label %for.end.loopexit, label %for.body.lr.ph
61 for.body.lr.ph:
62   %1 = load ptr, ptr @ptr, align 8
63   %2 = load i32, ptr @e, align 4
64   br label %for.body
66 for.cond:
67   %inc = add nsw i32 %i.05, 1
68   %cmp = icmp slt i32 %i.05, %2
69   br i1 %cmp, label %for.body, label %for.cond.for.end.loopexit_crit_edge
71 for.body:
72   %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.cond ]
73   %idxprom = sext i32 %i.05 to i64
74   %arrayidx = getelementptr inbounds i32, ptr %1, i64 %idxprom
75   %3 = load i32, ptr %arrayidx, align 4
76   %tobool = icmp eq i32 %3, 0
77   br i1 %tobool, label %if.then, label %for.cond
79 if.then:
80   %i.05.lcssa = phi i32 [ %i.05, %for.body ]
81   store i32 %i.05.lcssa, ptr @idx, align 4
82   br label %for.end
84 for.cond.for.end.loopexit_crit_edge:
85   br label %for.end.loopexit
87 for.end.loopexit:
88   br label %for.end
90 for.end:
91   %4 = load i32, ptr @idx, align 4
92   ret i32 %4
96 define void @test2(ptr %a, ptr %b, i8 %limit) {
97 ; CHECK-LABEL: @test2(
98 ; CHECK-NEXT:  entry:
99 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[LIMIT:%.*]] to i32
100 ; CHECK-NEXT:    br i1 undef, label [[FOR_COND1_PREHEADER_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
101 ; CHECK:       for.cond1.preheader.us.preheader:
102 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[CONV]], i32 1)
103 ; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
104 ; CHECK:       for.cond1.preheader.preheader:
105 ; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER:%.*]]
106 ; CHECK:       for.cond1.preheader.us:
107 ; CHECK-NEXT:    [[INDVARS_IV3:%.*]] = phi i64 [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ], [ [[INDVARS_IV_NEXT4:%.*]], [[FOR_INC13_US:%.*]] ]
108 ; CHECK-NEXT:    br i1 true, label [[FOR_BODY4_LR_PH_US:%.*]], label [[FOR_INC13_US]]
109 ; CHECK:       for.inc13.us.loopexit:
110 ; CHECK-NEXT:    br label [[FOR_INC13_US]]
111 ; CHECK:       for.inc13.us:
112 ; CHECK-NEXT:    [[INDVARS_IV_NEXT4]] = add nuw nsw i64 [[INDVARS_IV3]], 1
113 ; CHECK-NEXT:    [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT4]], 4
114 ; CHECK-NEXT:    br i1 [[EXITCOND6]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_END_LOOPEXIT1:%.*]]
115 ; CHECK:       for.body4.us:
116 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[FOR_BODY4_LR_PH_US]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY4_US:%.*]] ]
117 ; CHECK-NEXT:    [[ARRAYIDX6_US:%.*]] = getelementptr inbounds [8 x i8], ptr [[A:%.*]], i64 [[INDVARS_IV3]], i64 [[INDVARS_IV]]
118 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX6_US]], align 1
119 ; CHECK-NEXT:    [[IDXPROM7_US:%.*]] = zext i8 [[TMP0]] to i64
120 ; CHECK-NEXT:    [[ARRAYIDX8_US:%.*]] = getelementptr inbounds i8, ptr [[B:%.*]], i64 [[IDXPROM7_US]]
121 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX8_US]], align 1
122 ; CHECK-NEXT:    store i8 [[TMP1]], ptr [[ARRAYIDX6_US]], align 1
123 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
124 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT:%.*]]
125 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY4_US]], label [[FOR_INC13_US_LOOPEXIT:%.*]]
126 ; CHECK:       for.body4.lr.ph.us:
127 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT]] = zext i32 [[SMAX]] to i64
128 ; CHECK-NEXT:    br label [[FOR_BODY4_US]]
129 ; CHECK:       for.cond1.preheader:
130 ; CHECK-NEXT:    br i1 false, label [[FOR_INC13:%.*]], label [[FOR_INC13]]
131 ; CHECK:       for.inc13:
132 ; CHECK-NEXT:    br i1 false, label [[FOR_COND1_PREHEADER]], label [[FOR_END_LOOPEXIT:%.*]]
133 ; CHECK:       for.end.loopexit:
134 ; CHECK-NEXT:    br label [[FOR_END:%.*]]
135 ; CHECK:       for.end.loopexit1:
136 ; CHECK-NEXT:    br label [[FOR_END]]
137 ; CHECK:       for.end:
138 ; CHECK-NEXT:    ret void
140 entry:
141   %conv = zext i8 %limit to i32
142   br i1 undef, label %for.cond1.preheader, label %for.cond1.preheader.us
144 for.cond1.preheader.us:
145   %storemerge5.us = phi i32 [ 0, %entry ], [ %inc14.us, %for.inc13.us ]
146   br i1 true, label %for.body4.lr.ph.us, label %for.inc13.us
148 for.inc13.us:
149   %inc14.us = add nsw i32 %storemerge5.us, 1
150   %cmp.us = icmp slt i32 %inc14.us, 4
151   br i1 %cmp.us, label %for.cond1.preheader.us, label %for.end
153 for.body4.us:
154   %storemerge14.us = phi i32 [ 0, %for.body4.lr.ph.us ], [ %inc.us, %for.body4.us ]
155   %idxprom.us = sext i32 %storemerge14.us to i64
156   %arrayidx6.us = getelementptr inbounds [8 x i8], ptr %a, i64 %idxprom5.us, i64 %idxprom.us
157   %0 = load i8, ptr %arrayidx6.us, align 1
158   %idxprom7.us = zext i8 %0 to i64
159   %arrayidx8.us = getelementptr inbounds i8, ptr %b, i64 %idxprom7.us
160   %1 = load i8, ptr %arrayidx8.us, align 1
161   store i8 %1, ptr %arrayidx6.us, align 1
162   %inc.us = add nsw i32 %storemerge14.us, 1
163   %cmp2.us = icmp slt i32 %inc.us, %conv
164   br i1 %cmp2.us, label %for.body4.us, label %for.inc13.us
166 for.body4.lr.ph.us:
167   %idxprom5.us = sext i32 %storemerge5.us to i64
168   br label %for.body4.us
170 for.cond1.preheader:
171   %storemerge5 = phi i32 [ 0, %entry ], [ %inc14, %for.inc13 ]
172   br i1 false, label %for.inc13, label %for.inc13
174 for.inc13:
175   %inc14 = add nsw i32 %storemerge5, 1
176   %cmp = icmp slt i32 %inc14, 4
177   br i1 %cmp, label %for.cond1.preheader, label %for.end
179 for.end:
180   ret void
184 define i32 @test3(ptr %a, i32 %b) {
185 ; CHECK-LABEL: @test3(
186 ; CHECK-NEXT:  entry:
187 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B:%.*]], i32 0)
188 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
189 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
190 ; CHECK:       for.cond:
191 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
192 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
193 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
194 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
195 ; CHECK:       for.body:
196 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
197 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
198 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP0]]
199 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
200 ; CHECK-NEXT:    br label [[FOR_COND]]
201 ; CHECK:       for.end:
202 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ]
203 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
205 entry:
206   br label %for.cond
208 for.cond:
209   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
210   %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
211   %cmp = icmp slt i32 %i.0, %b
212   br i1 %cmp, label %for.body, label %for.end
214 for.body:
215   %idxprom = sext i32 %i.0 to i64
216   %arrayidx = getelementptr inbounds i32, ptr %a, i64 %idxprom
217   %0 = load i32, ptr %arrayidx, align 4
218   %add = add nsw i32 %sum.0, %0
219   %inc = add nsw i32 %i.0, 1
220   br label %for.cond
222 for.end:
223   ret i32 %sum.0
226 declare i32 @fn1(i8 signext)
228 ; PR21030
230 define i32 @test4(i32 %a) {
231 ; CHECK-LABEL: @test4(
232 ; CHECK-NEXT:  entry:
233 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
234 ; CHECK:       for.body:
235 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 253, [[ENTRY:%.*]] ]
236 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[INDVARS_IV]]
237 ; CHECK-NEXT:    [[CONV3:%.*]] = trunc i32 [[OR]] to i8
238 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @fn1(i8 signext [[CONV3]])
239 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i32 [[INDVARS_IV]], -1
240 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i32 [[INDVARS_IV_NEXT]] to i8
241 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[TMP0]], -14
242 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
243 ; CHECK:       for.end:
244 ; CHECK-NEXT:    ret i32 0
246 entry:
247   br label %for.body
249 for.body:
250   %c.07 = phi i8 [ -3, %entry ], [ %dec, %for.body ]
251   %conv6 = zext i8 %c.07 to i32
252   %or = or i32 %a, %conv6
253   %conv3 = trunc i32 %or to i8
254   %call = call i32 @fn1(i8 signext %conv3)
255   %dec = add i8 %c.07, -1
256   %cmp = icmp sgt i8 %dec, -14
257   br i1 %cmp, label %for.body, label %for.end
259 for.end:
260   ret i32 0
264 define i32 @test5(ptr %a, i32 %b) {
265 ; CHECK-LABEL: @test5(
266 ; CHECK-NEXT:  entry:
267 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[B:%.*]] to i64
268 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
269 ; CHECK:       for.cond:
270 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
271 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
272 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP0]]
273 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
274 ; CHECK:       for.body:
275 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
276 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
277 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]]
278 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
279 ; CHECK-NEXT:    br label [[FOR_COND]]
280 ; CHECK:       for.end:
281 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ]
282 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
284 entry:
285   br label %for.cond
287 for.cond:
288   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
289   %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
290   %cmp = icmp ule i32 %i.0, %b
291   br i1 %cmp, label %for.body, label %for.end
293 for.body:
294   %idxprom = zext i32 %i.0 to i64
295   %arrayidx = getelementptr inbounds i32, ptr %a, i64 %idxprom
296   %0 = load i32, ptr %arrayidx, align 4
297   %add = add nsw i32 %sum.0, %0
298   %inc = add nsw i32 %i.0, 1
299   br label %for.cond
301 for.end:
302   ret i32 %sum.0
305 define i32 @test6(ptr %a, i32 %b) {
306 ; CHECK-LABEL: @test6(
307 ; CHECK-NEXT:  entry:
308 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B:%.*]], i32 -1)
309 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[SMAX]], 1
310 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP0]] to i64
311 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
312 ; CHECK:       for.cond:
313 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
314 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
315 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
316 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
317 ; CHECK:       for.body:
318 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
319 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
320 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]]
321 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
322 ; CHECK-NEXT:    br label [[FOR_COND]]
323 ; CHECK:       for.end:
324 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ]
325 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
327 entry:
328   br label %for.cond
330 for.cond:
331   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
332   %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
333   %cmp = icmp sle i32 %i.0, %b
334   br i1 %cmp, label %for.body, label %for.end
336 for.body:
337   %idxprom = zext i32 %i.0 to i64
338   %arrayidx = getelementptr inbounds i32, ptr %a, i64 %idxprom
339   %0 = load i32, ptr %arrayidx, align 4
340   %add = add nsw i32 %sum.0, %0
341   %inc = add nsw i32 %i.0, 1
342   br label %for.cond
344 for.end:
345   ret i32 %sum.0
348 define i32 @test7(ptr %a, i32 %b) {
349 ; CHECK-LABEL: @test7(
350 ; CHECK-NEXT:  entry:
351 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[B:%.*]] to i64
352 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 -1)
353 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[SMAX]], 2
354 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP1]] to i64
355 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
356 ; CHECK:       for.cond:
357 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
358 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
359 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP0]]
360 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
361 ; CHECK:       for.body:
362 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
363 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
364 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]]
365 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
366 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
367 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND]], label [[FOR_END]]
368 ; CHECK:       for.end:
369 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
370 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
372 entry:
373   br label %for.cond
375 for.cond:
376   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
377   %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
378   %cmp = icmp ule i32 %i.0, %b
379   br i1 %cmp, label %for.body, label %for.end
381 for.body:
382   %idxprom = sext i32 %i.0 to i64
383   %arrayidx = getelementptr inbounds i32, ptr %a, i64 %idxprom
384   %0 = load i32, ptr %arrayidx, align 4
385   %add = add nsw i32 %sum.0, %0
386   %inc = add nsw i32 %i.0, 1
387   %cmp2 = icmp sle i32 %i.0, %b
388   br i1 %cmp2, label %for.cond, label %for.end
390 for.end:
391   ret i32 %sum.0
394 define i32 @test8(ptr %a, i32 %b, i32 %init) {
395 ;     Note: %indvars.iv is the sign extension of %i.0
396 ; CHECK-LABEL: @test8(
397 ; CHECK-NEXT:  entry:
398 ; CHECK-NEXT:    [[E:%.*]] = icmp sgt i32 [[INIT:%.*]], 0
399 ; CHECK-NEXT:    br i1 [[E]], label [[FOR_COND_PREHEADER:%.*]], label [[LEAVE:%.*]]
400 ; CHECK:       for.cond.preheader:
401 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[INIT]] to i64
402 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[B:%.*]] to i64
403 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
404 ; CHECK:       for.cond:
405 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ]
406 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ]
407 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP1]]
408 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
409 ; CHECK:       for.body:
410 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
411 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
412 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]]
413 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
414 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i64 0, [[INDVARS_IV_NEXT]]
415 ; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[FOR_END]]
416 ; CHECK:       for.end:
417 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
418 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
419 ; CHECK:       leave:
420 ; CHECK-NEXT:    ret i32 0
422 entry:
423   %e = icmp sgt i32 %init, 0
424   br i1 %e, label %for.cond, label %leave
426 for.cond:
427   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
428   %i.0 = phi i32 [ %init, %entry ], [ %inc, %for.body ]
429   %cmp = icmp ule i32 %i.0, %b
430   br i1 %cmp, label %for.body, label %for.end
432 for.body:
433   %idxprom = sext i32 %i.0 to i64
434   %arrayidx = getelementptr inbounds i32, ptr %a, i64 %idxprom
435   %0 = load i32, ptr %arrayidx, align 4
436   %add = add nsw i32 %sum.0, %0
437   %inc = add nsw i32 %i.0, 1
438   %cmp2 = icmp slt i32 0, %inc
439   br i1 %cmp2, label %for.cond, label %for.end
441 for.end:
442   ret i32 %sum.0
444 leave:
445   ret i32 0
448 define i32 @test9(ptr %a, i32 %b, i32 %init) {
449 ;     Note: %indvars.iv is the zero extension of %i.0
450 ; CHECK-LABEL: @test9(
451 ; CHECK-NEXT:  entry:
452 ; CHECK-NEXT:    [[E:%.*]] = icmp sgt i32 [[INIT:%.*]], 0
453 ; CHECK-NEXT:    br i1 [[E]], label [[FOR_COND_PREHEADER:%.*]], label [[LEAVE:%.*]]
454 ; CHECK:       for.cond.preheader:
455 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[INIT]] to i64
456 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[INIT]], i32 [[B:%.*]])
457 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
458 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
459 ; CHECK:       for.cond:
460 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ]
461 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ]
462 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
463 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
464 ; CHECK:       for.body:
465 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
466 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
467 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]]
468 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
469 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
470 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 0, [[TMP2]]
471 ; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[FOR_END]]
472 ; CHECK:       for.end:
473 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
474 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
475 ; CHECK:       leave:
476 ; CHECK-NEXT:    ret i32 0
478 entry:
479   %e = icmp sgt i32 %init, 0
480   br i1 %e, label %for.cond, label %leave
482 for.cond:
483   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
484   %i.0 = phi i32 [ %init, %entry ], [ %inc, %for.body ]
485   %cmp = icmp slt i32 %i.0, %b
486   br i1 %cmp, label %for.body, label %for.end
488 for.body:
489   %idxprom = zext i32 %i.0 to i64
490   %arrayidx = getelementptr inbounds i32, ptr %a, i64 %idxprom
491   %0 = load i32, ptr %arrayidx, align 4
492   %add = add nsw i32 %sum.0, %0
493   %inc = add nsw i32 %i.0, 1
494   %cmp2 = icmp slt i32 0, %inc
495   br i1 %cmp2, label %for.cond, label %for.end
497 for.end:
498   ret i32 %sum.0
500 leave:
501   ret i32 0
504 declare void @consume.i64(i64)
505 declare void @consume.i1(i1)
507 define i32 @test10(i32 %v) {
508 ; CHECK-LABEL: @test10(
509 ; CHECK-NEXT:  entry:
510 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i32 [[V:%.*]] to i64
511 ; CHECK-NEXT:    br label [[LOOP:%.*]]
512 ; CHECK:       loop:
513 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
514 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
515 ; CHECK-NEXT:    [[TMP0:%.*]] = mul nsw i64 [[INDVARS_IV]], -1
516 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], [[SEXT]]
517 ; CHECK-NEXT:    call void @consume.i1(i1 [[TMP1]])
518 ; CHECK-NEXT:    call void @consume.i64(i64 [[TMP0]])
519 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 11
520 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE:%.*]]
521 ; CHECK:       leave:
522 ; CHECK-NEXT:    ret i32 22
524   entry:
525   br label %loop
527   loop:
529   %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
530   %i.inc = add i32 %i, 1
531   %iv = mul i32 %i, -1
532   %cmp = icmp eq i32 %iv, %v
533   call void @consume.i1(i1 %cmp)
534   %be.cond = icmp slt i32 %i.inc, 11
535   %ext = sext i32 %iv to i64
536   call void @consume.i64(i64 %ext)
537   br i1 %be.cond, label %loop, label %leave
539   leave:
540   ret i32 22
543 ; TODO: We don't really need trunc/zext here because when iv.next overflows,
544 ; its value is not used.
545 define i32 @test11(i32 %start, ptr %p, ptr %q) {
546 ; CHECK-LABEL: @test11(
547 ; CHECK-NEXT:  entry:
548 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
549 ; CHECK-NEXT:    br label [[LOOP:%.*]]
550 ; CHECK:       loop:
551 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
552 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
553 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
554 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
555 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
556 ; CHECK:       backedge:
557 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
558 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
559 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
560 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
561 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
562 ; CHECK:       exit:
563 ; CHECK-NEXT:    ret i32 0
564 ; CHECK:       failure:
565 ; CHECK-NEXT:    unreachable
567 entry:
568   br label %loop
570 loop:
571   %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
572   %iv.next = add i32 %iv, -1
573   %cond = icmp eq i32 %iv, 0
574   br i1 %cond, label %exit, label %backedge
576 backedge:
577   %index = zext i32 %iv.next to i64
578   %store.addr = getelementptr i32, ptr %p, i64 %index
579   store i32 1, ptr %store.addr
580   %load.addr = getelementptr i32, ptr %q, i64 %index
581   %stop = load i32, ptr %q
582   %loop.cond = icmp eq i32 %stop, 0
583   br i1 %loop.cond, label %loop, label %failure
585 exit:
586   ret i32 0
588 failure:
589   unreachable
592 define i32 @test12(i32 %start, ptr %p, ptr %q) {
593 ; CHECK-LABEL: @test12(
594 ; CHECK-NEXT:  entry:
595 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
596 ; CHECK-NEXT:    br label [[LOOP:%.*]]
597 ; CHECK:       loop:
598 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
599 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
600 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
601 ; CHECK:       backedge:
602 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
603 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
604 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
605 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
606 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
607 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
608 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
609 ; CHECK:       exit:
610 ; CHECK-NEXT:    ret i32 0
611 ; CHECK:       failure:
612 ; CHECK-NEXT:    unreachable
614 entry:
615   br label %loop
617 loop:
618   %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
619   %cond = icmp eq i32 %iv, 0
620   br i1 %cond, label %exit, label %backedge
622 backedge:
623   %iv.next = add i32 %iv, -1
624   %index = zext i32 %iv.next to i64
625   %store.addr = getelementptr i32, ptr %p, i64 %index
626   store i32 1, ptr %store.addr
627   %load.addr = getelementptr i32, ptr %q, i64 %index
628   %stop = load i32, ptr %q
629   %loop.cond = icmp eq i32 %stop, 0
630   br i1 %loop.cond, label %loop, label %failure
632 exit:
633   ret i32 0
635 failure:
636   unreachable
639 define i32 @test13(i32 %start, ptr %p, ptr %q) {
640 ; CHECK-LABEL: @test13(
641 ; CHECK-NEXT:  entry:
642 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
643 ; CHECK-NEXT:    br label [[LOOP:%.*]]
644 ; CHECK:       loop:
645 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
646 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
647 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
648 ; CHECK:       backedge:
649 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
650 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
651 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
652 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
653 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
654 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
655 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
656 ; CHECK:       exit:
657 ; CHECK-NEXT:    ret i32 0
658 ; CHECK:       failure:
659 ; CHECK-NEXT:    unreachable
661 entry:
662   br label %loop
664 loop:
665   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
666   %cond = icmp eq i32 %iv, 0
667   br i1 %cond, label %exit, label %backedge
669 backedge:
670   %foo = add i32 %iv, -1
671   %index = zext i32 %foo to i64
672   %store.addr = getelementptr i32, ptr %p, i64 %index
673   store i32 1, ptr %store.addr
674   %load.addr = getelementptr i32, ptr %q, i64 %index
675   %stop = load i32, ptr %q
676   %loop.cond = icmp eq i32 %stop, 0
677   %iv.next.1 = add i32 %iv, -1
678   br i1 %loop.cond, label %loop, label %failure
680 exit:
681   ret i32 0
683 failure:
684   unreachable
687 define i32 @test14(i32 %start, ptr %p, ptr %q) {
688 ; CHECK-LABEL: @test14(
689 ; CHECK-NEXT:  entry:
690 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
691 ; CHECK-NEXT:    br label [[LOOP:%.*]]
692 ; CHECK:       loop:
693 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
694 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
695 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
696 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
697 ; CHECK:       backedge:
698 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
699 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
700 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
701 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
702 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
703 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
704 ; CHECK:       exit:
705 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
706 ; CHECK-NEXT:    ret i32 [[TMP2]]
707 ; CHECK:       failure:
708 ; CHECK-NEXT:    unreachable
710 entry:
711   br label %loop
713 loop:
714   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
715   %cond = icmp eq i32 %iv, 0
716   %foo = add i32 %iv, -1
717   br i1 %cond, label %exit, label %backedge
719 backedge:
720   %index = zext i32 %foo to i64
721   %store.addr = getelementptr i32, ptr %p, i64 %index
722   store i32 1, ptr %store.addr
723   %load.addr = getelementptr i32, ptr %q, i64 %index
724   %stop = load i32, ptr %q
725   %loop.cond = icmp eq i32 %stop, 0
726   %iv.next.1 = add i32 %iv, -1
727   br i1 %loop.cond, label %loop, label %failure
729 exit:
730   ret i32 %foo
732 failure:
733   unreachable
736 declare void @test14a-callee(i1 %cond)
738 ; Same as @test14 but with unwind exit.
739 ; Trunc instructions must be added below the landing pad.
740 define i32 @test14a(i32 %start, ptr %p, ptr %q, i1 %c) personality i1 1 {
741 ; CHECK-LABEL: @test14a(
742 ; CHECK-NEXT:  entry:
743 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
744 ; CHECK-NEXT:    br label [[LOOP:%.*]]
745 ; CHECK:       loop:
746 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
747 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
748 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
749 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
750 ; CHECK:       backedge:
751 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
752 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
753 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
754 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
755 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
756 ; CHECK-NEXT:    invoke void @test14a-callee(i1 [[LOOP_COND]])
757 ; CHECK-NEXT:            to label [[LOOP]] unwind label [[EXCEPTION:%.*]]
758 ; CHECK:       exit:
759 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
760 ; CHECK-NEXT:    ret i32 [[TMP2]]
761 ; CHECK:       exception:
762 ; CHECK-NEXT:    [[FOO_LCSSA1_WIDE:%.*]] = phi i64 [ [[TMP1]], [[BACKEDGE]] ]
763 ; CHECK-NEXT:    [[TMP3:%.*]] = landingpad i1
764 ; CHECK-NEXT:            cleanup
765 ; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 [[FOO_LCSSA1_WIDE]] to i32
766 ; CHECK-NEXT:    ret i32 [[TMP4]]
768 entry:
769   br label %loop
771 loop:
772   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
773   %cond = icmp eq i32 %iv, 0
774   %foo = add i32 %iv, -1
775   br i1 %cond, label %exit, label %backedge
777 backedge:
778   %index = zext i32 %foo to i64
779   %store.addr = getelementptr i32, ptr %p, i64 %index
780   store i32 1, ptr %store.addr
781   %load.addr = getelementptr i32, ptr %q, i64 %index
782   %stop = load i32, ptr %q
783   %loop.cond = icmp eq i32 %stop, 0
784   %iv.next.1 = add i32 %iv, -1
785   invoke void @test14a-callee(i1 %loop.cond) to label %loop unwind label %exception
787 exit:
788   ret i32 %foo
790 exception:
791   landingpad i1
792   cleanup
793   ret i32 %foo
796 declare void @use(i32 %arg)
798 define i32 @test15(i32 %start, ptr %p, ptr %q) {
799 ; CHECK-LABEL: @test15(
800 ; CHECK-NEXT:  entry:
801 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
802 ; CHECK-NEXT:    br label [[LOOP:%.*]]
803 ; CHECK:       loop:
804 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
805 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
806 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
807 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
808 ; CHECK:       backedge:
809 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
810 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
811 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
812 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
813 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
814 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
815 ; CHECK:       exit:
816 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
817 ; CHECK-NEXT:    call void @use(i32 [[TMP2]])
818 ; CHECK-NEXT:    ret i32 [[TMP2]]
819 ; CHECK:       failure:
820 ; CHECK-NEXT:    [[FOO_LCSSA1_WIDE:%.*]] = phi i64 [ [[TMP1]], [[BACKEDGE]] ]
821 ; CHECK-NEXT:    [[TMP3:%.*]] = trunc i64 [[FOO_LCSSA1_WIDE]] to i32
822 ; CHECK-NEXT:    call void @use(i32 [[TMP3]])
823 ; CHECK-NEXT:    unreachable
825 entry:
826   br label %loop
828 loop:
829   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
830   %cond = icmp eq i32 %iv, 0
831   %foo = add i32 %iv, -1
832   br i1 %cond, label %exit, label %backedge
834 backedge:
835   %index = zext i32 %foo to i64
836   %store.addr = getelementptr i32, ptr %p, i64 %index
837   store i32 1, ptr %store.addr
838   %load.addr = getelementptr i32, ptr %q, i64 %index
839   %stop = load i32, ptr %q
840   %loop.cond = icmp eq i32 %stop, 0
841   %iv.next.1 = add i32 %iv, -1
842   br i1 %loop.cond, label %loop, label %failure
844 exit:
845   call void @use(i32 %foo)
846   ret i32 %foo
848 failure:
849   call void @use(i32 %foo)
850   unreachable
853 define i32 @test16_unsigned_pos1(i32 %start, ptr %p, ptr %q, i32 %x) {
854 ; CHECK-LABEL: @test16_unsigned_pos1(
855 ; CHECK-NEXT:  entry:
856 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
857 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[TMP0]], -1
858 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[X:%.*]] to i64
859 ; CHECK-NEXT:    [[ICMP_USER_WIDE_FIRST_ITER:%.*]] = icmp ult i64 [[TMP1]], [[TMP2]]
860 ; CHECK-NEXT:    br label [[LOOP:%.*]]
861 ; CHECK:       loop:
862 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
863 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
864 ; CHECK-NEXT:    [[TMP3:%.*]] = add nsw i64 [[INDVARS_IV]], -1
865 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
866 ; CHECK:       guarded:
867 ; CHECK-NEXT:    br i1 [[ICMP_USER_WIDE_FIRST_ITER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
868 ; CHECK:       backedge:
869 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP3]]
870 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
871 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
872 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
873 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
874 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
875 ; CHECK:       exit:
876 ; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 -1 to i32
877 ; CHECK-NEXT:    call void @use(i32 [[TMP4]])
878 ; CHECK-NEXT:    ret i32 [[TMP4]]
879 ; CHECK:       failure:
880 ; CHECK-NEXT:    [[FOO_LCSSA2_WIDE:%.*]] = phi i64 [ [[TMP3]], [[BACKEDGE]] ]
881 ; CHECK-NEXT:    [[TMP5:%.*]] = trunc i64 [[FOO_LCSSA2_WIDE]] to i32
882 ; CHECK-NEXT:    call void @use(i32 [[TMP5]])
883 ; CHECK-NEXT:    unreachable
884 ; CHECK:       side_exit:
885 ; CHECK-NEXT:    ret i32 0
887 entry:
888   br label %loop
890 loop:
891   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
892   %cond = icmp eq i32 %iv, 0
893   %foo = add i32 %iv, -1
894   br i1 %cond, label %exit, label %guarded
896 guarded:
897   %icmp_user = icmp ult i32 %foo, %x
898   br i1 %icmp_user, label %backedge, label %side_exit
900 backedge:
901   %index = zext i32 %foo to i64
902   %store.addr = getelementptr i32, ptr %p, i64 %index
903   store i32 1, ptr %store.addr
904   %load.addr = getelementptr i32, ptr %q, i64 %index
905   %stop = load i32, ptr %q
906   %loop.cond = icmp eq i32 %stop, 0
907   %iv.next.1 = add i32 %iv, -1
908   br i1 %loop.cond, label %loop, label %failure
910 exit:
911   call void @use(i32 %foo)
912   ret i32 %foo
914 failure:
915   call void @use(i32 %foo)
916   unreachable
918 side_exit:
919   ret i32 0
922 ; TODO: We can widen here despite the icmp user of %foo in guarded block.
923 define i32 @test16_unsigned_pos2(i32 %start, ptr %p, ptr %q, i32 %x) {
924 ; CHECK-LABEL: @test16_unsigned_pos2(
925 ; CHECK-NEXT:  entry:
926 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
927 ; CHECK-NEXT:    br label [[LOOP:%.*]]
928 ; CHECK:       loop:
929 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
930 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
931 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
932 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
933 ; CHECK:       guarded:
934 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[X:%.*]] to i64
935 ; CHECK-NEXT:    [[ICMP_USER_WIDE:%.*]] = icmp ne i64 [[TMP1]], [[TMP2]]
936 ; CHECK-NEXT:    br i1 [[ICMP_USER_WIDE]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
937 ; CHECK:       backedge:
938 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
939 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
940 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
941 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
942 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
943 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
944 ; CHECK:       exit:
945 ; CHECK-NEXT:    [[TMP3:%.*]] = trunc i64 -1 to i32
946 ; CHECK-NEXT:    call void @use(i32 [[TMP3]])
947 ; CHECK-NEXT:    ret i32 [[TMP3]]
948 ; CHECK:       failure:
949 ; CHECK-NEXT:    [[FOO_LCSSA2_WIDE:%.*]] = phi i64 [ [[TMP1]], [[BACKEDGE]] ]
950 ; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 [[FOO_LCSSA2_WIDE]] to i32
951 ; CHECK-NEXT:    call void @use(i32 [[TMP4]])
952 ; CHECK-NEXT:    unreachable
953 ; CHECK:       side_exit:
954 ; CHECK-NEXT:    ret i32 0
956 entry:
957   br label %loop
959 loop:
960   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
961   %cond = icmp eq i32 %iv, 0
962   %foo = add i32 %iv, -1
963   br i1 %cond, label %exit, label %guarded
965 guarded:
966   %icmp_user = icmp ne i32 %foo, %x
967   br i1 %icmp_user, label %backedge, label %side_exit
969 backedge:
970   %index = zext i32 %foo to i64
971   %store.addr = getelementptr i32, ptr %p, i64 %index
972   store i32 1, ptr %store.addr
973   %load.addr = getelementptr i32, ptr %q, i64 %index
974   %stop = load i32, ptr %q
975   %loop.cond = icmp eq i32 %stop, 0
976   %iv.next.1 = add i32 %iv, -1
977   br i1 %loop.cond, label %loop, label %failure
979 exit:
980   call void @use(i32 %foo)
981   ret i32 %foo
983 failure:
984   call void @use(i32 %foo)
985   unreachable
987 side_exit:
988   ret i32 0
991 ; icmp slt user in guarded block prevents widening.
992 define i32 @test16_unsigned_neg(i32 %start, ptr %p, ptr %q, i32 %x) {
993 ; CHECK-LABEL: @test16_unsigned_neg(
994 ; CHECK-NEXT:  entry:
995 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
996 ; CHECK-NEXT:    br label [[LOOP:%.*]]
997 ; CHECK:       loop:
998 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
999 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
1000 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[INDVARS_IV]] to i32
1001 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[TMP1]], -1
1002 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1003 ; CHECK:       guarded:
1004 ; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp slt i32 [[FOO]], [[X:%.*]]
1005 ; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1006 ; CHECK:       backedge:
1007 ; CHECK-NEXT:    [[INDEX:%.*]] = zext i32 [[FOO]] to i64
1008 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
1009 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
1010 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, ptr [[Q:%.*]], i64 [[INDEX]]
1011 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q]], align 4
1012 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1013 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
1014 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1015 ; CHECK:       exit:
1016 ; CHECK-NEXT:    call void @use(i32 -1)
1017 ; CHECK-NEXT:    ret i32 -1
1018 ; CHECK:       failure:
1019 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1020 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1021 ; CHECK-NEXT:    unreachable
1022 ; CHECK:       side_exit:
1023 ; CHECK-NEXT:    ret i32 0
1025 entry:
1026   br label %loop
1028 loop:
1029   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1030   %cond = icmp eq i32 %iv, 0
1031   %foo = add i32 %iv, -1
1032   br i1 %cond, label %exit, label %guarded
1034 guarded:
1035   %icmp_user = icmp slt i32 %foo, %x
1036   br i1 %icmp_user, label %backedge, label %side_exit
1038 backedge:
1039   %index = zext i32 %foo to i64
1040   %store.addr = getelementptr i32, ptr %p, i64 %index
1041   store i32 1, ptr %store.addr
1042   %load.addr = getelementptr i32, ptr %q, i64 %index
1043   %stop = load i32, ptr %q
1044   %loop.cond = icmp eq i32 %stop, 0
1045   %iv.next.1 = add i32 %iv, -1
1046   br i1 %loop.cond, label %loop, label %failure
1048 exit:
1049   call void @use(i32 %foo)
1050   ret i32 %foo
1052 failure:
1053   call void @use(i32 %foo)
1054   unreachable
1056 side_exit:
1057   ret i32 0
1060 ; TODO: We can widen here despite the icmp user of %foo in guarded block.
1061 define i32 @test16_signed_pos1(i32 %start, ptr %p, ptr %q, i32 %x) {
1062 ; CHECK-LABEL: @test16_signed_pos1(
1063 ; CHECK-NEXT:  entry:
1064 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1065 ; CHECK:       loop:
1066 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT_1:%.*]], [[BACKEDGE:%.*]] ]
1067 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[IV]], 0
1068 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[IV]], -1
1069 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1070 ; CHECK:       guarded:
1071 ; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp slt i32 [[FOO]], [[X:%.*]]
1072 ; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1073 ; CHECK:       backedge:
1074 ; CHECK-NEXT:    [[INDEX:%.*]] = sext i32 [[FOO]] to i64
1075 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
1076 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
1077 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, ptr [[Q:%.*]], i64 [[INDEX]]
1078 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q]], align 4
1079 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1080 ; CHECK-NEXT:    [[IV_NEXT_1]] = add i32 [[IV]], -1
1081 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1082 ; CHECK:       exit:
1083 ; CHECK-NEXT:    call void @use(i32 -1)
1084 ; CHECK-NEXT:    ret i32 -1
1085 ; CHECK:       failure:
1086 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1087 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1088 ; CHECK-NEXT:    unreachable
1089 ; CHECK:       side_exit:
1090 ; CHECK-NEXT:    ret i32 0
1092 entry:
1093   br label %loop
1095 loop:
1096   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1097   %cond = icmp eq i32 %iv, 0
1098   %foo = add i32 %iv, -1
1099   br i1 %cond, label %exit, label %guarded
1101 guarded:
1102   %icmp_user = icmp slt i32 %foo, %x
1103   br i1 %icmp_user, label %backedge, label %side_exit
1105 backedge:
1106   %index = sext i32 %foo to i64
1107   %store.addr = getelementptr i32, ptr %p, i64 %index
1108   store i32 1, ptr %store.addr
1109   %load.addr = getelementptr i32, ptr %q, i64 %index
1110   %stop = load i32, ptr %q
1111   %loop.cond = icmp eq i32 %stop, 0
1112   %iv.next.1 = add i32 %iv, -1
1113   br i1 %loop.cond, label %loop, label %failure
1115 exit:
1116   call void @use(i32 %foo)
1117   ret i32 %foo
1119 failure:
1120   call void @use(i32 %foo)
1121   unreachable
1123 side_exit:
1124   ret i32 0
1127 ; TODO: We can widen here despite the icmp user of %foo in guarded block.
1128 define i32 @test16_signed_pos2(i32 %start, ptr %p, ptr %q, i32 %x) {
1129 ; CHECK-LABEL: @test16_signed_pos2(
1130 ; CHECK-NEXT:  entry:
1131 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1132 ; CHECK:       loop:
1133 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT_1:%.*]], [[BACKEDGE:%.*]] ]
1134 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[IV]], 0
1135 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[IV]], -1
1136 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1137 ; CHECK:       guarded:
1138 ; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp ne i32 [[FOO]], [[X:%.*]]
1139 ; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1140 ; CHECK:       backedge:
1141 ; CHECK-NEXT:    [[INDEX:%.*]] = sext i32 [[FOO]] to i64
1142 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
1143 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
1144 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, ptr [[Q:%.*]], i64 [[INDEX]]
1145 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q]], align 4
1146 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1147 ; CHECK-NEXT:    [[IV_NEXT_1]] = add i32 [[IV]], -1
1148 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1149 ; CHECK:       exit:
1150 ; CHECK-NEXT:    call void @use(i32 -1)
1151 ; CHECK-NEXT:    ret i32 -1
1152 ; CHECK:       failure:
1153 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1154 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1155 ; CHECK-NEXT:    unreachable
1156 ; CHECK:       side_exit:
1157 ; CHECK-NEXT:    ret i32 0
1159 entry:
1160   br label %loop
1162 loop:
1163   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1164   %cond = icmp eq i32 %iv, 0
1165   %foo = add i32 %iv, -1
1166   br i1 %cond, label %exit, label %guarded
1168 guarded:
1169   %icmp_user = icmp ne i32 %foo, %x
1170   br i1 %icmp_user, label %backedge, label %side_exit
1172 backedge:
1173   %index = sext i32 %foo to i64
1174   %store.addr = getelementptr i32, ptr %p, i64 %index
1175   store i32 1, ptr %store.addr
1176   %load.addr = getelementptr i32, ptr %q, i64 %index
1177   %stop = load i32, ptr %q
1178   %loop.cond = icmp eq i32 %stop, 0
1179   %iv.next.1 = add i32 %iv, -1
1180   br i1 %loop.cond, label %loop, label %failure
1182 exit:
1183   call void @use(i32 %foo)
1184   ret i32 %foo
1186 failure:
1187   call void @use(i32 %foo)
1188   unreachable
1190 side_exit:
1191   ret i32 0
1194 ; icmp ult user in guarded block prevents widening.
1195 define i32 @test16_signed_neg(i32 %start, ptr %p, ptr %q, i32 %x) {
1196 ; CHECK-LABEL: @test16_signed_neg(
1197 ; CHECK-NEXT:  entry:
1198 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[START:%.*]], -1
1199 ; CHECK-NEXT:    [[ICMP_USER_FIRST_ITER:%.*]] = icmp ult i32 [[TMP0]], [[X:%.*]]
1200 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1201 ; CHECK:       loop:
1202 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START]], [[ENTRY:%.*]] ], [ [[IV_NEXT_1:%.*]], [[BACKEDGE:%.*]] ]
1203 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[IV]], 0
1204 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[IV]], -1
1205 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1206 ; CHECK:       guarded:
1207 ; CHECK-NEXT:    br i1 [[ICMP_USER_FIRST_ITER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1208 ; CHECK:       backedge:
1209 ; CHECK-NEXT:    [[INDEX:%.*]] = sext i32 [[FOO]] to i64
1210 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
1211 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
1212 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, ptr [[Q:%.*]], i64 [[INDEX]]
1213 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q]], align 4
1214 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1215 ; CHECK-NEXT:    [[IV_NEXT_1]] = add i32 [[IV]], -1
1216 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1217 ; CHECK:       exit:
1218 ; CHECK-NEXT:    call void @use(i32 -1)
1219 ; CHECK-NEXT:    ret i32 -1
1220 ; CHECK:       failure:
1221 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1222 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1223 ; CHECK-NEXT:    unreachable
1224 ; CHECK:       side_exit:
1225 ; CHECK-NEXT:    ret i32 0
1227 entry:
1228   br label %loop
1230 loop:
1231   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1232   %cond = icmp eq i32 %iv, 0
1233   %foo = add i32 %iv, -1
1234   br i1 %cond, label %exit, label %guarded
1236 guarded:
1237   %icmp_user = icmp ult i32 %foo, %x
1238   br i1 %icmp_user, label %backedge, label %side_exit
1240 backedge:
1241   %index = sext i32 %foo to i64
1242   %store.addr = getelementptr i32, ptr %p, i64 %index
1243   store i32 1, ptr %store.addr
1244   %load.addr = getelementptr i32, ptr %q, i64 %index
1245   %stop = load i32, ptr %q
1246   %loop.cond = icmp eq i32 %stop, 0
1247   %iv.next.1 = add i32 %iv, -1
1248   br i1 %loop.cond, label %loop, label %failure
1250 exit:
1251   call void @use(i32 %foo)
1252   ret i32 %foo
1254 failure:
1255   call void @use(i32 %foo)
1256   unreachable
1258 side_exit:
1259   ret i32 0
1262 define i32 @test17(ptr %p, i32 %len) {
1263 ; CHECK-LABEL: @test17(
1264 ; CHECK-NEXT:  entry:
1265 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[LEN:%.*]] to i64
1266 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1267 ; CHECK:       loop:
1268 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
1269 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
1270 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
1271 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
1272 ; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
1273 ; CHECK:       backedge:
1274 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[TMP1]]
1275 ; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[ADDR]] unordered, align 4
1276 ; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], 0
1277 ; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
1278 ; CHECK:       exit:
1279 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
1280 ; CHECK-NEXT:    ret i32 [[TMP2]]
1281 ; CHECK:       failure:
1282 ; CHECK-NEXT:    unreachable
1284 entry:
1285   br label %loop
1287 loop:
1288   %iv = phi i32 [ %iv.next, %backedge ], [ %len, %entry ]
1289   %iv.next = add i32 %iv, -1
1290   %cond_1 = icmp eq i32 %iv, 0
1291   br i1 %cond_1, label %exit, label %backedge
1293 backedge:
1294   %iv.next.wide = zext i32 %iv.next to i64
1295   %addr = getelementptr inbounds i32, ptr %p, i64 %iv.next.wide
1296   %loaded = load atomic i32, ptr %addr unordered, align 4
1297   %cond_2 = icmp eq i32 %loaded, 0
1298   br i1 %cond_2, label %failure, label %loop
1300 exit:
1301   ret i32 %iv.next
1303 failure:
1304   unreachable
1307 declare void @foo(i64 %v)
1308 declare void @bar(i32 %v)
1310 define void @test18() {
1311 ; CHECK-LABEL: @test18(
1312 ; CHECK-NEXT:  entry:
1313 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1314 ; CHECK:       loop:
1315 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1316 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1317 ; CHECK-NEXT:    [[INDVARS2:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
1318 ; CHECK-NEXT:    call void @bar(i32 [[INDVARS2]])
1319 ; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
1320 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
1321 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1322 ; CHECK:       exit:
1323 ; CHECK-NEXT:    ret void
1325 entry:
1326   br label %loop
1328 loop:                                             ; preds = %loop, %entry
1329   %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1330   %val1 = phi i32 [ %val1.inc, %loop ], [ 0, %entry ]
1331   %val1.inc = add i32 %val1, 1
1332   %iv.next = add i32 %iv, 1
1333   call void @bar(i32 %val1.inc)
1334   %iv.wide = zext i32 %iv to i64
1335   call void @foo(i64 %iv.wide)
1336   %loop.cond = icmp eq i32 %iv, 1000
1337   br i1 %loop.cond, label %exit, label %loop
1339 exit:                                             ; preds = %loop
1340   ret void
1343 define void @test19() {
1344 ; CHECK-LABEL: @test19(
1345 ; CHECK-NEXT:  entry:
1346 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1347 ; CHECK:       loop:
1348 ; CHECK-NEXT:    [[VAL1:%.*]] = phi i64 [ [[VAL1_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1349 ; CHECK-NEXT:    [[VAL1_INC]] = add nuw nsw i64 [[VAL1]], 1
1350 ; CHECK-NEXT:    call void @foo(i64 [[VAL1_INC]])
1351 ; CHECK-NEXT:    call void @foo(i64 [[VAL1]])
1352 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[VAL1]], 1000
1353 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1354 ; CHECK:       exit:
1355 ; CHECK-NEXT:    ret void
1357 entry:
1358   br label %loop
1360 loop:                                             ; preds = %loop, %entry
1361   %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1362   %val1 = phi i64 [ %val1.inc, %loop ], [ 0, %entry ]
1363   %val1.inc = add i64 %val1, 1
1364   %iv.next = add i32 %iv, 1
1365   call void @foo(i64 %val1.inc)
1366   %iv.wide = zext i32 %iv to i64
1367   call void @foo(i64 %iv.wide)
1368   %loop.cond = icmp eq i32 %iv, 1000
1369   br i1 %loop.cond, label %exit, label %loop
1371 exit:                                             ; preds = %loop
1372   ret void
1375 define void @test20() {
1376 ; CHECK-LABEL: @test20(
1377 ; CHECK-NEXT:  entry:
1378 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1379 ; CHECK:       loop:
1380 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1381 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1382 ; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
1383 ; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
1384 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
1385 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1386 ; CHECK:       exit:
1387 ; CHECK-NEXT:    ret void
1389 entry:
1390   br label %loop
1392 loop:                                             ; preds = %loop, %entry
1393   %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1394   %val1 = phi i32 [ %val1.inc, %loop ], [ 0, %entry ]
1395   %val1.inc = add i32 %val1, 1
1396   %iv.next = add i32 %iv, 1
1397   %val1.wide = zext i32 %val1 to i64
1398   call void @foo(i64 %val1.wide)
1399   %iv.wide = zext i32 %iv to i64
1400   call void @foo(i64 %iv.wide)
1401   %loop.cond = icmp eq i32 %iv, 1000
1402   br i1 %loop.cond, label %exit, label %loop
1404 exit:                                             ; preds = %loop
1405   ret void
1408 define void @test21(ptr %ptr) {
1409 ; CHECK-LABEL: @test21(
1410 ; CHECK-NEXT:  entry:
1411 ; CHECK-NEXT:    store i32 0, ptr [[PTR:%.*]], align 4
1412 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1413 ; CHECK:       loop:
1414 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1415 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1416 ; CHECK-NEXT:    [[INDVARS:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
1417 ; CHECK-NEXT:    store i32 [[INDVARS]], ptr [[PTR]], align 4
1418 ; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
1419 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
1420 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1421 ; CHECK:       exit:
1422 ; CHECK-NEXT:    ret void
1424 entry:
1425   store i32 0, ptr %ptr, align 4
1426   br label %loop
1428 loop:                                             ; preds = %loop, %entry
1429   %val = phi i32 [ %val.inc, %loop ], [ 0, %entry ]
1430   %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1431   %val.inc = add i32 %val, 1
1432   store i32 %val.inc, ptr %ptr, align 4
1433   %iv.wide = zext i32 %iv to i64
1434   call void @foo(i64 %iv.wide)
1435   %iv.next = add i32 %iv, 1
1436   %loop.cond = icmp eq i32 %iv, 1000
1437   br i1 %loop.cond, label %exit, label %loop
1439 exit:                                             ; preds = %loop
1440   ret void
1443 ; Don't perform replacement here; SCEV won't recognize the new PHI as an
1444 ; induction variable.
1445 define void @test22(ptr %ptr) {
1446 ; CHECK-LABEL: @test22(
1447 ; CHECK-NEXT:  entry:
1448 ; CHECK-NEXT:    store i16 0, ptr [[PTR:%.*]], align 4
1449 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1450 ; CHECK:       loop:
1451 ; CHECK-NEXT:    [[VAL:%.*]] = phi i16 [ [[VAL_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1452 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]
1453 ; CHECK-NEXT:    [[VAL_INC]] = add i16 [[VAL]], 1
1454 ; CHECK-NEXT:    store i16 [[VAL_INC]], ptr [[PTR]], align 4
1455 ; CHECK-NEXT:    [[IV_WIDE:%.*]] = zext i32 [[IV]] to i64
1456 ; CHECK-NEXT:    call void @foo(i64 [[IV_WIDE]])
1457 ; CHECK-NEXT:    [[IV_NEXT]] = zext i16 [[VAL_INC]] to i32
1458 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[IV]], 1000
1459 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1460 ; CHECK:       exit:
1461 ; CHECK-NEXT:    ret void
1463 entry:
1464   store i16 0, ptr %ptr, align 4
1465   br label %loop
1467 loop:                                             ; preds = %loop, %entry
1468   %val = phi i16 [ %val.inc, %loop ], [ 0, %entry ]
1469   %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1470   %val.inc = add i16 %val, 1
1471   store i16 %val.inc, ptr %ptr, align 4
1472   %iv.wide = zext i32 %iv to i64
1473   call void @foo(i64 %iv.wide)
1474   %iv.next = zext i16 %val.inc to i32
1475   %loop.cond = icmp eq i32 %iv, 1000
1476   br i1 %loop.cond, label %exit, label %loop
1478 exit:                                             ; preds = %loop
1479   ret void