[RISCV] Rename a lambda to have plural nouns to reflect that it contains a loop. NFC
[llvm-project.git] / llvm / test / Transforms / IndVarSimplify / AArch64 / widen-loop-comp.ll
blob257816650017af9a2ee2b5e79937590d565915f6
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 nuw nsw 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, i1 %arg) {
97 ; CHECK-LABEL: @test2(
98 ; CHECK-NEXT:  entry:
99 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[LIMIT:%.*]] to i32
100 ; CHECK-NEXT:    br i1 %arg, 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 %arg, 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 nuw 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:    [[TMP1:%.*]] = add nuw nsw i64 [[TMP0]], 1
269 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
270 ; CHECK:       for.cond:
271 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
272 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
273 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[TMP1]]
274 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
275 ; CHECK:       for.body:
276 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
277 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
278 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]]
279 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
280 ; CHECK-NEXT:    br label [[FOR_COND]]
281 ; CHECK:       for.end:
282 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ]
283 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
285 entry:
286   br label %for.cond
288 for.cond:
289   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
290   %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
291   %cmp = icmp ule i32 %i.0, %b
292   br i1 %cmp, label %for.body, label %for.end
294 for.body:
295   %idxprom = zext i32 %i.0 to i64
296   %arrayidx = getelementptr inbounds i32, ptr %a, i64 %idxprom
297   %0 = load i32, ptr %arrayidx, align 4
298   %add = add nsw i32 %sum.0, %0
299   %inc = add nsw i32 %i.0, 1
300   br label %for.cond
302 for.end:
303   ret i32 %sum.0
306 define i32 @test6(ptr %a, i32 %b) {
307 ; CHECK-LABEL: @test6(
308 ; CHECK-NEXT:  entry:
309 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B:%.*]], i32 -1)
310 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[SMAX]], 1
311 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP0]] to i64
312 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
313 ; CHECK:       for.cond:
314 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
315 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
316 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
317 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
318 ; CHECK:       for.body:
319 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
320 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
321 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]]
322 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
323 ; CHECK-NEXT:    br label [[FOR_COND]]
324 ; CHECK:       for.end:
325 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ]
326 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
328 entry:
329   br label %for.cond
331 for.cond:
332   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
333   %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
334   %cmp = icmp sle i32 %i.0, %b
335   br i1 %cmp, label %for.body, label %for.end
337 for.body:
338   %idxprom = zext i32 %i.0 to i64
339   %arrayidx = getelementptr inbounds i32, ptr %a, i64 %idxprom
340   %0 = load i32, ptr %arrayidx, align 4
341   %add = add nsw i32 %sum.0, %0
342   %inc = add nsw i32 %i.0, 1
343   br label %for.cond
345 for.end:
346   ret i32 %sum.0
349 define i32 @test7(ptr %a, i32 %b) {
350 ; CHECK-LABEL: @test7(
351 ; CHECK-NEXT:  entry:
352 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[B:%.*]] to i64
353 ; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i64 [[TMP0]], 1
354 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 -1)
355 ; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[SMAX]], 2
356 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP2]] to i64
357 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
358 ; CHECK:       for.cond:
359 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
360 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
361 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[TMP1]]
362 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
363 ; CHECK:       for.body:
364 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
365 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
366 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP3]]
367 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
368 ; CHECK-NEXT:    [[EXITCOND2:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
369 ; CHECK-NEXT:    br i1 [[EXITCOND2]], label [[FOR_COND]], label [[FOR_END]]
370 ; CHECK:       for.end:
371 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
372 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
374 entry:
375   br label %for.cond
377 for.cond:
378   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
379   %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
380   %cmp = icmp ule i32 %i.0, %b
381   br i1 %cmp, label %for.body, label %for.end
383 for.body:
384   %idxprom = sext i32 %i.0 to i64
385   %arrayidx = getelementptr inbounds i32, ptr %a, i64 %idxprom
386   %0 = load i32, ptr %arrayidx, align 4
387   %add = add nsw i32 %sum.0, %0
388   %inc = add nsw i32 %i.0, 1
389   %cmp2 = icmp sle i32 %i.0, %b
390   br i1 %cmp2, label %for.cond, label %for.end
392 for.end:
393   ret i32 %sum.0
396 define i32 @test8(ptr %a, i32 %b, i32 %init) {
397 ;     Note: %indvars.iv is the sign extension of %i.0
398 ; CHECK-LABEL: @test8(
399 ; CHECK-NEXT:  entry:
400 ; CHECK-NEXT:    [[E:%.*]] = icmp sgt i32 [[INIT:%.*]], 0
401 ; CHECK-NEXT:    br i1 [[E]], label [[FOR_COND_PREHEADER:%.*]], label [[LEAVE:%.*]]
402 ; CHECK:       for.cond.preheader:
403 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[INIT]] to i64
404 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[B:%.*]] to i64
405 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
406 ; CHECK:       for.cond:
407 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ]
408 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ]
409 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP1]]
410 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
411 ; CHECK:       for.body:
412 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
413 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
414 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]]
415 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
416 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i64 0, [[INDVARS_IV_NEXT]]
417 ; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[FOR_END]]
418 ; CHECK:       for.end:
419 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
420 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
421 ; CHECK:       leave:
422 ; CHECK-NEXT:    ret i32 0
424 entry:
425   %e = icmp sgt i32 %init, 0
426   br i1 %e, label %for.cond, label %leave
428 for.cond:
429   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
430   %i.0 = phi i32 [ %init, %entry ], [ %inc, %for.body ]
431   %cmp = icmp ule i32 %i.0, %b
432   br i1 %cmp, label %for.body, label %for.end
434 for.body:
435   %idxprom = sext i32 %i.0 to i64
436   %arrayidx = getelementptr inbounds i32, ptr %a, i64 %idxprom
437   %0 = load i32, ptr %arrayidx, align 4
438   %add = add nsw i32 %sum.0, %0
439   %inc = add nsw i32 %i.0, 1
440   %cmp2 = icmp slt i32 0, %inc
441   br i1 %cmp2, label %for.cond, label %for.end
443 for.end:
444   ret i32 %sum.0
446 leave:
447   ret i32 0
450 define i32 @test9(ptr %a, i32 %b, i32 %init) {
451 ;     Note: %indvars.iv is the zero extension of %i.0
452 ; CHECK-LABEL: @test9(
453 ; CHECK-NEXT:  entry:
454 ; CHECK-NEXT:    [[E:%.*]] = icmp sgt i32 [[INIT:%.*]], 0
455 ; CHECK-NEXT:    br i1 [[E]], label [[FOR_COND_PREHEADER:%.*]], label [[LEAVE:%.*]]
456 ; CHECK:       for.cond.preheader:
457 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[INIT]] to i64
458 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[INIT]], i32 [[B:%.*]])
459 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
460 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
461 ; CHECK:       for.cond:
462 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ]
463 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ]
464 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
465 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
466 ; CHECK:       for.body:
467 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
468 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
469 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]]
470 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
471 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc nuw i64 [[INDVARS_IV_NEXT]] to i32
472 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 0, [[TMP2]]
473 ; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[FOR_END]]
474 ; CHECK:       for.end:
475 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
476 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
477 ; CHECK:       leave:
478 ; CHECK-NEXT:    ret i32 0
480 entry:
481   %e = icmp sgt i32 %init, 0
482   br i1 %e, label %for.cond, label %leave
484 for.cond:
485   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
486   %i.0 = phi i32 [ %init, %entry ], [ %inc, %for.body ]
487   %cmp = icmp slt i32 %i.0, %b
488   br i1 %cmp, label %for.body, label %for.end
490 for.body:
491   %idxprom = zext i32 %i.0 to i64
492   %arrayidx = getelementptr inbounds i32, ptr %a, i64 %idxprom
493   %0 = load i32, ptr %arrayidx, align 4
494   %add = add nsw i32 %sum.0, %0
495   %inc = add nsw i32 %i.0, 1
496   %cmp2 = icmp slt i32 0, %inc
497   br i1 %cmp2, label %for.cond, label %for.end
499 for.end:
500   ret i32 %sum.0
502 leave:
503   ret i32 0
506 declare void @consume.i64(i64)
507 declare void @consume.i1(i1)
509 define i32 @test10(i32 %v) {
510 ; CHECK-LABEL: @test10(
511 ; CHECK-NEXT:  entry:
512 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i32 [[V:%.*]] to i64
513 ; CHECK-NEXT:    br label [[LOOP:%.*]]
514 ; CHECK:       loop:
515 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
516 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
517 ; CHECK-NEXT:    [[TMP0:%.*]] = mul nsw i64 [[INDVARS_IV]], -1
518 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], [[SEXT]]
519 ; CHECK-NEXT:    call void @consume.i1(i1 [[TMP1]])
520 ; CHECK-NEXT:    call void @consume.i64(i64 [[TMP0]])
521 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 11
522 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE:%.*]]
523 ; CHECK:       leave:
524 ; CHECK-NEXT:    ret i32 22
526   entry:
527   br label %loop
529   loop:
531   %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
532   %i.inc = add i32 %i, 1
533   %iv = mul i32 %i, -1
534   %cmp = icmp eq i32 %iv, %v
535   call void @consume.i1(i1 %cmp)
536   %be.cond = icmp slt i32 %i.inc, 11
537   %ext = sext i32 %iv to i64
538   call void @consume.i64(i64 %ext)
539   br i1 %be.cond, label %loop, label %leave
541   leave:
542   ret i32 22
545 ; TODO: We don't really need trunc/zext here because when iv.next overflows,
546 ; its value is not used.
547 define i32 @test11(i32 %start, ptr %p, ptr %q) {
548 ; CHECK-LABEL: @test11(
549 ; CHECK-NEXT:  entry:
550 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
551 ; CHECK-NEXT:    br label [[LOOP:%.*]]
552 ; CHECK:       loop:
553 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
554 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
555 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
556 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
557 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
558 ; CHECK:       backedge:
559 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
560 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
561 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
562 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
563 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
564 ; CHECK:       exit:
565 ; CHECK-NEXT:    ret i32 0
566 ; CHECK:       failure:
567 ; CHECK-NEXT:    unreachable
569 entry:
570   br label %loop
572 loop:
573   %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
574   %iv.next = add i32 %iv, -1
575   %cond = icmp eq i32 %iv, 0
576   br i1 %cond, label %exit, label %backedge
578 backedge:
579   %index = zext i32 %iv.next to i64
580   %store.addr = getelementptr i32, ptr %p, i64 %index
581   store i32 1, ptr %store.addr
582   %load.addr = getelementptr i32, ptr %q, i64 %index
583   %stop = load i32, ptr %q
584   %loop.cond = icmp eq i32 %stop, 0
585   br i1 %loop.cond, label %loop, label %failure
587 exit:
588   ret i32 0
590 failure:
591   unreachable
594 define i32 @test12(i32 %start, ptr %p, ptr %q) {
595 ; CHECK-LABEL: @test12(
596 ; CHECK-NEXT:  entry:
597 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
598 ; CHECK-NEXT:    br label [[LOOP:%.*]]
599 ; CHECK:       loop:
600 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
601 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
602 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
603 ; CHECK:       backedge:
604 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
605 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
606 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
607 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
608 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
609 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
610 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
611 ; CHECK:       exit:
612 ; CHECK-NEXT:    ret i32 0
613 ; CHECK:       failure:
614 ; CHECK-NEXT:    unreachable
616 entry:
617   br label %loop
619 loop:
620   %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
621   %cond = icmp eq i32 %iv, 0
622   br i1 %cond, label %exit, label %backedge
624 backedge:
625   %iv.next = add i32 %iv, -1
626   %index = zext i32 %iv.next to i64
627   %store.addr = getelementptr i32, ptr %p, i64 %index
628   store i32 1, ptr %store.addr
629   %load.addr = getelementptr i32, ptr %q, i64 %index
630   %stop = load i32, ptr %q
631   %loop.cond = icmp eq i32 %stop, 0
632   br i1 %loop.cond, label %loop, label %failure
634 exit:
635   ret i32 0
637 failure:
638   unreachable
641 define i32 @test13(i32 %start, ptr %p, ptr %q) {
642 ; CHECK-LABEL: @test13(
643 ; CHECK-NEXT:  entry:
644 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
645 ; CHECK-NEXT:    br label [[LOOP:%.*]]
646 ; CHECK:       loop:
647 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
648 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
649 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
650 ; CHECK:       backedge:
651 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
652 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
653 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
654 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
655 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
656 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
657 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
658 ; CHECK:       exit:
659 ; CHECK-NEXT:    ret i32 0
660 ; CHECK:       failure:
661 ; CHECK-NEXT:    unreachable
663 entry:
664   br label %loop
666 loop:
667   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
668   %cond = icmp eq i32 %iv, 0
669   br i1 %cond, label %exit, label %backedge
671 backedge:
672   %foo = add i32 %iv, -1
673   %index = zext i32 %foo to i64
674   %store.addr = getelementptr i32, ptr %p, i64 %index
675   store i32 1, ptr %store.addr
676   %load.addr = getelementptr i32, ptr %q, i64 %index
677   %stop = load i32, ptr %q
678   %loop.cond = icmp eq i32 %stop, 0
679   %iv.next.1 = add i32 %iv, -1
680   br i1 %loop.cond, label %loop, label %failure
682 exit:
683   ret i32 0
685 failure:
686   unreachable
689 define i32 @test14(i32 %start, ptr %p, ptr %q) {
690 ; CHECK-LABEL: @test14(
691 ; CHECK-NEXT:  entry:
692 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
693 ; CHECK-NEXT:    br label [[LOOP:%.*]]
694 ; CHECK:       loop:
695 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
696 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
697 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
698 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
699 ; CHECK:       backedge:
700 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
701 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
702 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
703 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
704 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
705 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
706 ; CHECK:       exit:
707 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
708 ; CHECK-NEXT:    ret i32 [[TMP2]]
709 ; CHECK:       failure:
710 ; CHECK-NEXT:    unreachable
712 entry:
713   br label %loop
715 loop:
716   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
717   %cond = icmp eq i32 %iv, 0
718   %foo = add i32 %iv, -1
719   br i1 %cond, label %exit, label %backedge
721 backedge:
722   %index = zext i32 %foo to i64
723   %store.addr = getelementptr i32, ptr %p, i64 %index
724   store i32 1, ptr %store.addr
725   %load.addr = getelementptr i32, ptr %q, i64 %index
726   %stop = load i32, ptr %q
727   %loop.cond = icmp eq i32 %stop, 0
728   %iv.next.1 = add i32 %iv, -1
729   br i1 %loop.cond, label %loop, label %failure
731 exit:
732   ret i32 %foo
734 failure:
735   unreachable
738 declare void @test14a-callee(i1 %cond)
740 ; Same as @test14 but with unwind exit.
741 ; Trunc instructions must be added below the landing pad.
742 define i32 @test14a(i32 %start, ptr %p, ptr %q, i1 %c) personality i1 1 {
743 ; CHECK-LABEL: @test14a(
744 ; CHECK-NEXT:  entry:
745 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
746 ; CHECK-NEXT:    br label [[LOOP:%.*]]
747 ; CHECK:       loop:
748 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
749 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
750 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
751 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
752 ; CHECK:       backedge:
753 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
754 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
755 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
756 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
757 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
758 ; CHECK-NEXT:    invoke void @test14a-callee(i1 [[LOOP_COND]])
759 ; CHECK-NEXT:            to label [[LOOP]] unwind label [[EXCEPTION:%.*]]
760 ; CHECK:       exit:
761 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
762 ; CHECK-NEXT:    ret i32 [[TMP2]]
763 ; CHECK:       exception:
764 ; CHECK-NEXT:    [[FOO_LCSSA1_WIDE:%.*]] = phi i64 [ [[TMP1]], [[BACKEDGE]] ]
765 ; CHECK-NEXT:    [[TMP3:%.*]] = landingpad i1
766 ; CHECK-NEXT:            cleanup
767 ; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 [[FOO_LCSSA1_WIDE]] to i32
768 ; CHECK-NEXT:    ret i32 [[TMP4]]
770 entry:
771   br label %loop
773 loop:
774   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
775   %cond = icmp eq i32 %iv, 0
776   %foo = add i32 %iv, -1
777   br i1 %cond, label %exit, label %backedge
779 backedge:
780   %index = zext i32 %foo to i64
781   %store.addr = getelementptr i32, ptr %p, i64 %index
782   store i32 1, ptr %store.addr
783   %load.addr = getelementptr i32, ptr %q, i64 %index
784   %stop = load i32, ptr %q
785   %loop.cond = icmp eq i32 %stop, 0
786   %iv.next.1 = add i32 %iv, -1
787   invoke void @test14a-callee(i1 %loop.cond) to label %loop unwind label %exception
789 exit:
790   ret i32 %foo
792 exception:
793   landingpad i1
794   cleanup
795   ret i32 %foo
798 declare void @use(i32 %arg)
800 define i32 @test15(i32 %start, ptr %p, ptr %q) {
801 ; CHECK-LABEL: @test15(
802 ; CHECK-NEXT:  entry:
803 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
804 ; CHECK-NEXT:    br label [[LOOP:%.*]]
805 ; CHECK:       loop:
806 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
807 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
808 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
809 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
810 ; CHECK:       backedge:
811 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
812 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
813 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
814 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
815 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
816 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
817 ; CHECK:       exit:
818 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
819 ; CHECK-NEXT:    call void @use(i32 [[TMP2]])
820 ; CHECK-NEXT:    ret i32 [[TMP2]]
821 ; CHECK:       failure:
822 ; CHECK-NEXT:    [[FOO_LCSSA1_WIDE:%.*]] = phi i64 [ [[TMP1]], [[BACKEDGE]] ]
823 ; CHECK-NEXT:    [[TMP3:%.*]] = trunc i64 [[FOO_LCSSA1_WIDE]] to i32
824 ; CHECK-NEXT:    call void @use(i32 [[TMP3]])
825 ; CHECK-NEXT:    unreachable
827 entry:
828   br label %loop
830 loop:
831   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
832   %cond = icmp eq i32 %iv, 0
833   %foo = add i32 %iv, -1
834   br i1 %cond, label %exit, label %backedge
836 backedge:
837   %index = zext i32 %foo to i64
838   %store.addr = getelementptr i32, ptr %p, i64 %index
839   store i32 1, ptr %store.addr
840   %load.addr = getelementptr i32, ptr %q, i64 %index
841   %stop = load i32, ptr %q
842   %loop.cond = icmp eq i32 %stop, 0
843   %iv.next.1 = add i32 %iv, -1
844   br i1 %loop.cond, label %loop, label %failure
846 exit:
847   call void @use(i32 %foo)
848   ret i32 %foo
850 failure:
851   call void @use(i32 %foo)
852   unreachable
855 define i32 @test16_unsigned_pos1(i32 %start, ptr %p, ptr %q, i32 %x) {
856 ; CHECK-LABEL: @test16_unsigned_pos1(
857 ; CHECK-NEXT:  entry:
858 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
859 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[TMP0]], -1
860 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[X:%.*]] to i64
861 ; CHECK-NEXT:    [[ICMP_USER_WIDE_FIRST_ITER:%.*]] = icmp ult i64 [[TMP1]], [[TMP2]]
862 ; CHECK-NEXT:    br label [[LOOP:%.*]]
863 ; CHECK:       loop:
864 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
865 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
866 ; CHECK-NEXT:    [[TMP3:%.*]] = add nsw i64 [[INDVARS_IV]], -1
867 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
868 ; CHECK:       guarded:
869 ; CHECK-NEXT:    br i1 [[ICMP_USER_WIDE_FIRST_ITER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
870 ; CHECK:       backedge:
871 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP3]]
872 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
873 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
874 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
875 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
876 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
877 ; CHECK:       exit:
878 ; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 -1 to i32
879 ; CHECK-NEXT:    call void @use(i32 [[TMP4]])
880 ; CHECK-NEXT:    ret i32 [[TMP4]]
881 ; CHECK:       failure:
882 ; CHECK-NEXT:    [[FOO_LCSSA2_WIDE:%.*]] = phi i64 [ [[TMP3]], [[BACKEDGE]] ]
883 ; CHECK-NEXT:    [[TMP5:%.*]] = trunc i64 [[FOO_LCSSA2_WIDE]] to i32
884 ; CHECK-NEXT:    call void @use(i32 [[TMP5]])
885 ; CHECK-NEXT:    unreachable
886 ; CHECK:       side_exit:
887 ; CHECK-NEXT:    ret i32 0
889 entry:
890   br label %loop
892 loop:
893   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
894   %cond = icmp eq i32 %iv, 0
895   %foo = add i32 %iv, -1
896   br i1 %cond, label %exit, label %guarded
898 guarded:
899   %icmp_user = icmp ult i32 %foo, %x
900   br i1 %icmp_user, label %backedge, label %side_exit
902 backedge:
903   %index = zext i32 %foo to i64
904   %store.addr = getelementptr i32, ptr %p, i64 %index
905   store i32 1, ptr %store.addr
906   %load.addr = getelementptr i32, ptr %q, i64 %index
907   %stop = load i32, ptr %q
908   %loop.cond = icmp eq i32 %stop, 0
909   %iv.next.1 = add i32 %iv, -1
910   br i1 %loop.cond, label %loop, label %failure
912 exit:
913   call void @use(i32 %foo)
914   ret i32 %foo
916 failure:
917   call void @use(i32 %foo)
918   unreachable
920 side_exit:
921   ret i32 0
924 ; TODO: We can widen here despite the icmp user of %foo in guarded block.
925 define i32 @test16_unsigned_pos2(i32 %start, ptr %p, ptr %q, i32 %x) {
926 ; CHECK-LABEL: @test16_unsigned_pos2(
927 ; CHECK-NEXT:  entry:
928 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
929 ; CHECK-NEXT:    br label [[LOOP:%.*]]
930 ; CHECK:       loop:
931 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
932 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
933 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
934 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
935 ; CHECK:       guarded:
936 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[X:%.*]] to i64
937 ; CHECK-NEXT:    [[ICMP_USER_WIDE:%.*]] = icmp ne i64 [[TMP1]], [[TMP2]]
938 ; CHECK-NEXT:    br i1 [[ICMP_USER_WIDE]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
939 ; CHECK:       backedge:
940 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[TMP1]]
941 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
942 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q:%.*]], align 4
943 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
944 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
945 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
946 ; CHECK:       exit:
947 ; CHECK-NEXT:    [[TMP3:%.*]] = trunc i64 -1 to i32
948 ; CHECK-NEXT:    call void @use(i32 [[TMP3]])
949 ; CHECK-NEXT:    ret i32 [[TMP3]]
950 ; CHECK:       failure:
951 ; CHECK-NEXT:    [[FOO_LCSSA2_WIDE:%.*]] = phi i64 [ [[TMP1]], [[BACKEDGE]] ]
952 ; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 [[FOO_LCSSA2_WIDE]] to i32
953 ; CHECK-NEXT:    call void @use(i32 [[TMP4]])
954 ; CHECK-NEXT:    unreachable
955 ; CHECK:       side_exit:
956 ; CHECK-NEXT:    ret i32 0
958 entry:
959   br label %loop
961 loop:
962   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
963   %cond = icmp eq i32 %iv, 0
964   %foo = add i32 %iv, -1
965   br i1 %cond, label %exit, label %guarded
967 guarded:
968   %icmp_user = icmp ne i32 %foo, %x
969   br i1 %icmp_user, label %backedge, label %side_exit
971 backedge:
972   %index = zext i32 %foo to i64
973   %store.addr = getelementptr i32, ptr %p, i64 %index
974   store i32 1, ptr %store.addr
975   %load.addr = getelementptr i32, ptr %q, i64 %index
976   %stop = load i32, ptr %q
977   %loop.cond = icmp eq i32 %stop, 0
978   %iv.next.1 = add i32 %iv, -1
979   br i1 %loop.cond, label %loop, label %failure
981 exit:
982   call void @use(i32 %foo)
983   ret i32 %foo
985 failure:
986   call void @use(i32 %foo)
987   unreachable
989 side_exit:
990   ret i32 0
993 ; icmp slt user in guarded block prevents widening.
994 define i32 @test16_unsigned_neg(i32 %start, ptr %p, ptr %q, i32 %x) {
995 ; CHECK-LABEL: @test16_unsigned_neg(
996 ; CHECK-NEXT:  entry:
997 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
998 ; CHECK-NEXT:    br label [[LOOP:%.*]]
999 ; CHECK:       loop:
1000 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
1001 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
1002 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc nuw i64 [[INDVARS_IV]] to i32
1003 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[TMP1]], -1
1004 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1005 ; CHECK:       guarded:
1006 ; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp slt i32 [[FOO]], [[X:%.*]]
1007 ; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1008 ; CHECK:       backedge:
1009 ; CHECK-NEXT:    [[INDEX:%.*]] = zext i32 [[FOO]] to i64
1010 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
1011 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
1012 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, ptr [[Q:%.*]], i64 [[INDEX]]
1013 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q]], align 4
1014 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1015 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
1016 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1017 ; CHECK:       exit:
1018 ; CHECK-NEXT:    call void @use(i32 -1)
1019 ; CHECK-NEXT:    ret i32 -1
1020 ; CHECK:       failure:
1021 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1022 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1023 ; CHECK-NEXT:    unreachable
1024 ; CHECK:       side_exit:
1025 ; CHECK-NEXT:    ret i32 0
1027 entry:
1028   br label %loop
1030 loop:
1031   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1032   %cond = icmp eq i32 %iv, 0
1033   %foo = add i32 %iv, -1
1034   br i1 %cond, label %exit, label %guarded
1036 guarded:
1037   %icmp_user = icmp slt i32 %foo, %x
1038   br i1 %icmp_user, label %backedge, label %side_exit
1040 backedge:
1041   %index = zext i32 %foo to i64
1042   %store.addr = getelementptr i32, ptr %p, i64 %index
1043   store i32 1, ptr %store.addr
1044   %load.addr = getelementptr i32, ptr %q, i64 %index
1045   %stop = load i32, ptr %q
1046   %loop.cond = icmp eq i32 %stop, 0
1047   %iv.next.1 = add i32 %iv, -1
1048   br i1 %loop.cond, label %loop, label %failure
1050 exit:
1051   call void @use(i32 %foo)
1052   ret i32 %foo
1054 failure:
1055   call void @use(i32 %foo)
1056   unreachable
1058 side_exit:
1059   ret i32 0
1062 ; TODO: We can widen here despite the icmp user of %foo in guarded block.
1063 define i32 @test16_signed_pos1(i32 %start, ptr %p, ptr %q, i32 %x) {
1064 ; CHECK-LABEL: @test16_signed_pos1(
1065 ; CHECK-NEXT:  entry:
1066 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1067 ; CHECK:       loop:
1068 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT_1:%.*]], [[BACKEDGE:%.*]] ]
1069 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[IV]], 0
1070 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[IV]], -1
1071 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1072 ; CHECK:       guarded:
1073 ; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp slt i32 [[FOO]], [[X:%.*]]
1074 ; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1075 ; CHECK:       backedge:
1076 ; CHECK-NEXT:    [[INDEX:%.*]] = sext i32 [[FOO]] to i64
1077 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
1078 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
1079 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, ptr [[Q:%.*]], i64 [[INDEX]]
1080 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q]], align 4
1081 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1082 ; CHECK-NEXT:    [[IV_NEXT_1]] = add i32 [[IV]], -1
1083 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1084 ; CHECK:       exit:
1085 ; CHECK-NEXT:    call void @use(i32 -1)
1086 ; CHECK-NEXT:    ret i32 -1
1087 ; CHECK:       failure:
1088 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1089 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1090 ; CHECK-NEXT:    unreachable
1091 ; CHECK:       side_exit:
1092 ; CHECK-NEXT:    ret i32 0
1094 entry:
1095   br label %loop
1097 loop:
1098   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1099   %cond = icmp eq i32 %iv, 0
1100   %foo = add i32 %iv, -1
1101   br i1 %cond, label %exit, label %guarded
1103 guarded:
1104   %icmp_user = icmp slt i32 %foo, %x
1105   br i1 %icmp_user, label %backedge, label %side_exit
1107 backedge:
1108   %index = sext i32 %foo to i64
1109   %store.addr = getelementptr i32, ptr %p, i64 %index
1110   store i32 1, ptr %store.addr
1111   %load.addr = getelementptr i32, ptr %q, i64 %index
1112   %stop = load i32, ptr %q
1113   %loop.cond = icmp eq i32 %stop, 0
1114   %iv.next.1 = add i32 %iv, -1
1115   br i1 %loop.cond, label %loop, label %failure
1117 exit:
1118   call void @use(i32 %foo)
1119   ret i32 %foo
1121 failure:
1122   call void @use(i32 %foo)
1123   unreachable
1125 side_exit:
1126   ret i32 0
1129 ; TODO: We can widen here despite the icmp user of %foo in guarded block.
1130 define i32 @test16_signed_pos2(i32 %start, ptr %p, ptr %q, i32 %x) {
1131 ; CHECK-LABEL: @test16_signed_pos2(
1132 ; CHECK-NEXT:  entry:
1133 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1134 ; CHECK:       loop:
1135 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT_1:%.*]], [[BACKEDGE:%.*]] ]
1136 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[IV]], 0
1137 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[IV]], -1
1138 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1139 ; CHECK:       guarded:
1140 ; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp ne i32 [[FOO]], [[X:%.*]]
1141 ; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1142 ; CHECK:       backedge:
1143 ; CHECK-NEXT:    [[INDEX:%.*]] = sext i32 [[FOO]] to i64
1144 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
1145 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
1146 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, ptr [[Q:%.*]], i64 [[INDEX]]
1147 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q]], align 4
1148 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1149 ; CHECK-NEXT:    [[IV_NEXT_1]] = add i32 [[IV]], -1
1150 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1151 ; CHECK:       exit:
1152 ; CHECK-NEXT:    call void @use(i32 -1)
1153 ; CHECK-NEXT:    ret i32 -1
1154 ; CHECK:       failure:
1155 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1156 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1157 ; CHECK-NEXT:    unreachable
1158 ; CHECK:       side_exit:
1159 ; CHECK-NEXT:    ret i32 0
1161 entry:
1162   br label %loop
1164 loop:
1165   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1166   %cond = icmp eq i32 %iv, 0
1167   %foo = add i32 %iv, -1
1168   br i1 %cond, label %exit, label %guarded
1170 guarded:
1171   %icmp_user = icmp ne i32 %foo, %x
1172   br i1 %icmp_user, label %backedge, label %side_exit
1174 backedge:
1175   %index = sext i32 %foo to i64
1176   %store.addr = getelementptr i32, ptr %p, i64 %index
1177   store i32 1, ptr %store.addr
1178   %load.addr = getelementptr i32, ptr %q, i64 %index
1179   %stop = load i32, ptr %q
1180   %loop.cond = icmp eq i32 %stop, 0
1181   %iv.next.1 = add i32 %iv, -1
1182   br i1 %loop.cond, label %loop, label %failure
1184 exit:
1185   call void @use(i32 %foo)
1186   ret i32 %foo
1188 failure:
1189   call void @use(i32 %foo)
1190   unreachable
1192 side_exit:
1193   ret i32 0
1196 ; icmp ult user in guarded block prevents widening.
1197 define i32 @test16_signed_neg(i32 %start, ptr %p, ptr %q, i32 %x) {
1198 ; CHECK-LABEL: @test16_signed_neg(
1199 ; CHECK-NEXT:  entry:
1200 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[START:%.*]], -1
1201 ; CHECK-NEXT:    [[ICMP_USER_FIRST_ITER:%.*]] = icmp ult i32 [[TMP0]], [[X:%.*]]
1202 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1203 ; CHECK:       loop:
1204 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START]], [[ENTRY:%.*]] ], [ [[IV_NEXT_1:%.*]], [[BACKEDGE:%.*]] ]
1205 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[IV]], 0
1206 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[IV]], -1
1207 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1208 ; CHECK:       guarded:
1209 ; CHECK-NEXT:    br i1 [[ICMP_USER_FIRST_ITER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1210 ; CHECK:       backedge:
1211 ; CHECK-NEXT:    [[INDEX:%.*]] = sext i32 [[FOO]] to i64
1212 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
1213 ; CHECK-NEXT:    store i32 1, ptr [[STORE_ADDR]], align 4
1214 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, ptr [[Q:%.*]], i64 [[INDEX]]
1215 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, ptr [[Q]], align 4
1216 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1217 ; CHECK-NEXT:    [[IV_NEXT_1]] = add i32 [[IV]], -1
1218 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1219 ; CHECK:       exit:
1220 ; CHECK-NEXT:    call void @use(i32 -1)
1221 ; CHECK-NEXT:    ret i32 -1
1222 ; CHECK:       failure:
1223 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1224 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1225 ; CHECK-NEXT:    unreachable
1226 ; CHECK:       side_exit:
1227 ; CHECK-NEXT:    ret i32 0
1229 entry:
1230   br label %loop
1232 loop:
1233   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1234   %cond = icmp eq i32 %iv, 0
1235   %foo = add i32 %iv, -1
1236   br i1 %cond, label %exit, label %guarded
1238 guarded:
1239   %icmp_user = icmp ult i32 %foo, %x
1240   br i1 %icmp_user, label %backedge, label %side_exit
1242 backedge:
1243   %index = sext i32 %foo to i64
1244   %store.addr = getelementptr i32, ptr %p, i64 %index
1245   store i32 1, ptr %store.addr
1246   %load.addr = getelementptr i32, ptr %q, i64 %index
1247   %stop = load i32, ptr %q
1248   %loop.cond = icmp eq i32 %stop, 0
1249   %iv.next.1 = add i32 %iv, -1
1250   br i1 %loop.cond, label %loop, label %failure
1252 exit:
1253   call void @use(i32 %foo)
1254   ret i32 %foo
1256 failure:
1257   call void @use(i32 %foo)
1258   unreachable
1260 side_exit:
1261   ret i32 0
1264 define i32 @test17(ptr %p, i32 %len) {
1265 ; CHECK-LABEL: @test17(
1266 ; CHECK-NEXT:  entry:
1267 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[LEN:%.*]] to i64
1268 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1269 ; CHECK:       loop:
1270 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
1271 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
1272 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
1273 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
1274 ; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
1275 ; CHECK:       backedge:
1276 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[TMP1]]
1277 ; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[ADDR]] unordered, align 4
1278 ; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], 0
1279 ; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
1280 ; CHECK:       exit:
1281 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
1282 ; CHECK-NEXT:    ret i32 [[TMP2]]
1283 ; CHECK:       failure:
1284 ; CHECK-NEXT:    unreachable
1286 entry:
1287   br label %loop
1289 loop:
1290   %iv = phi i32 [ %iv.next, %backedge ], [ %len, %entry ]
1291   %iv.next = add i32 %iv, -1
1292   %cond_1 = icmp eq i32 %iv, 0
1293   br i1 %cond_1, label %exit, label %backedge
1295 backedge:
1296   %iv.next.wide = zext i32 %iv.next to i64
1297   %addr = getelementptr inbounds i32, ptr %p, i64 %iv.next.wide
1298   %loaded = load atomic i32, ptr %addr unordered, align 4
1299   %cond_2 = icmp eq i32 %loaded, 0
1300   br i1 %cond_2, label %failure, label %loop
1302 exit:
1303   ret i32 %iv.next
1305 failure:
1306   unreachable
1309 declare void @foo(i64 %v)
1310 declare void @bar(i32 %v)
1312 define void @test18() {
1313 ; CHECK-LABEL: @test18(
1314 ; CHECK-NEXT:  entry:
1315 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1316 ; CHECK:       loop:
1317 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1318 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1319 ; CHECK-NEXT:    [[INDVARS2:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
1320 ; CHECK-NEXT:    call void @bar(i32 [[INDVARS2]])
1321 ; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
1322 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
1323 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1324 ; CHECK:       exit:
1325 ; CHECK-NEXT:    ret void
1327 entry:
1328   br label %loop
1330 loop:                                             ; preds = %loop, %entry
1331   %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1332   %val1 = phi i32 [ %val1.inc, %loop ], [ 0, %entry ]
1333   %val1.inc = add i32 %val1, 1
1334   %iv.next = add i32 %iv, 1
1335   call void @bar(i32 %val1.inc)
1336   %iv.wide = zext i32 %iv to i64
1337   call void @foo(i64 %iv.wide)
1338   %loop.cond = icmp eq i32 %iv, 1000
1339   br i1 %loop.cond, label %exit, label %loop
1341 exit:                                             ; preds = %loop
1342   ret void
1345 define void @test19() {
1346 ; CHECK-LABEL: @test19(
1347 ; CHECK-NEXT:  entry:
1348 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1349 ; CHECK:       loop:
1350 ; CHECK-NEXT:    [[VAL1:%.*]] = phi i64 [ [[VAL1_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1351 ; CHECK-NEXT:    [[VAL1_INC]] = add nuw nsw i64 [[VAL1]], 1
1352 ; CHECK-NEXT:    call void @foo(i64 [[VAL1_INC]])
1353 ; CHECK-NEXT:    call void @foo(i64 [[VAL1]])
1354 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[VAL1]], 1000
1355 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1356 ; CHECK:       exit:
1357 ; CHECK-NEXT:    ret void
1359 entry:
1360   br label %loop
1362 loop:                                             ; preds = %loop, %entry
1363   %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1364   %val1 = phi i64 [ %val1.inc, %loop ], [ 0, %entry ]
1365   %val1.inc = add i64 %val1, 1
1366   %iv.next = add i32 %iv, 1
1367   call void @foo(i64 %val1.inc)
1368   %iv.wide = zext i32 %iv to i64
1369   call void @foo(i64 %iv.wide)
1370   %loop.cond = icmp eq i32 %iv, 1000
1371   br i1 %loop.cond, label %exit, label %loop
1373 exit:                                             ; preds = %loop
1374   ret void
1377 define void @test20() {
1378 ; CHECK-LABEL: @test20(
1379 ; CHECK-NEXT:  entry:
1380 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1381 ; CHECK:       loop:
1382 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1383 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1384 ; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
1385 ; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
1386 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
1387 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1388 ; CHECK:       exit:
1389 ; CHECK-NEXT:    ret void
1391 entry:
1392   br label %loop
1394 loop:                                             ; preds = %loop, %entry
1395   %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1396   %val1 = phi i32 [ %val1.inc, %loop ], [ 0, %entry ]
1397   %val1.inc = add i32 %val1, 1
1398   %iv.next = add i32 %iv, 1
1399   %val1.wide = zext i32 %val1 to i64
1400   call void @foo(i64 %val1.wide)
1401   %iv.wide = zext i32 %iv to i64
1402   call void @foo(i64 %iv.wide)
1403   %loop.cond = icmp eq i32 %iv, 1000
1404   br i1 %loop.cond, label %exit, label %loop
1406 exit:                                             ; preds = %loop
1407   ret void
1410 define void @test21(ptr %ptr) {
1411 ; CHECK-LABEL: @test21(
1412 ; CHECK-NEXT:  entry:
1413 ; CHECK-NEXT:    store i32 0, ptr [[PTR:%.*]], align 4
1414 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1415 ; CHECK:       loop:
1416 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1417 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1418 ; CHECK-NEXT:    [[INDVARS:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
1419 ; CHECK-NEXT:    store i32 [[INDVARS]], ptr [[PTR]], align 4
1420 ; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
1421 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
1422 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1423 ; CHECK:       exit:
1424 ; CHECK-NEXT:    ret void
1426 entry:
1427   store i32 0, ptr %ptr, align 4
1428   br label %loop
1430 loop:                                             ; preds = %loop, %entry
1431   %val = phi i32 [ %val.inc, %loop ], [ 0, %entry ]
1432   %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1433   %val.inc = add i32 %val, 1
1434   store i32 %val.inc, ptr %ptr, align 4
1435   %iv.wide = zext i32 %iv to i64
1436   call void @foo(i64 %iv.wide)
1437   %iv.next = add i32 %iv, 1
1438   %loop.cond = icmp eq i32 %iv, 1000
1439   br i1 %loop.cond, label %exit, label %loop
1441 exit:                                             ; preds = %loop
1442   ret void
1445 ; Don't perform replacement here; SCEV won't recognize the new PHI as an
1446 ; induction variable.
1447 define void @test22(ptr %ptr) {
1448 ; CHECK-LABEL: @test22(
1449 ; CHECK-NEXT:  entry:
1450 ; CHECK-NEXT:    store i16 0, ptr [[PTR:%.*]], align 4
1451 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1452 ; CHECK:       loop:
1453 ; CHECK-NEXT:    [[VAL:%.*]] = phi i16 [ [[VAL_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1454 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]
1455 ; CHECK-NEXT:    [[VAL_INC]] = add i16 [[VAL]], 1
1456 ; CHECK-NEXT:    store i16 [[VAL_INC]], ptr [[PTR]], align 4
1457 ; CHECK-NEXT:    [[IV_WIDE:%.*]] = zext i32 [[IV]] to i64
1458 ; CHECK-NEXT:    call void @foo(i64 [[IV_WIDE]])
1459 ; CHECK-NEXT:    [[IV_NEXT]] = zext i16 [[VAL_INC]] to i32
1460 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[IV]], 1000
1461 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1462 ; CHECK:       exit:
1463 ; CHECK-NEXT:    ret void
1465 entry:
1466   store i16 0, ptr %ptr, align 4
1467   br label %loop
1469 loop:                                             ; preds = %loop, %entry
1470   %val = phi i16 [ %val.inc, %loop ], [ 0, %entry ]
1471   %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1472   %val.inc = add i16 %val, 1
1473   store i16 %val.inc, ptr %ptr, align 4
1474   %iv.wide = zext i32 %iv to i64
1475   call void @foo(i64 %iv.wide)
1476   %iv.next = zext i16 %val.inc to i32
1477   %loop.cond = icmp eq i32 %iv, 1000
1478   br i1 %loop.cond, label %exit, label %loop
1480 exit:                                             ; preds = %loop
1481   ret void