[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / IndVarSimplify / widen-loop-comp.ll
blob469fa7acea9b620bc6685e87c471274c273472b1
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -indvars -scalar-evolution-use-expensive-range-sharpening -S | FileCheck %s
3 target triple = "aarch64--linux-gnu"
5 ; Provide legal integer types.
6 target datalayout = "n8:16:32:64"
9 ; Check the loop exit i32 compare instruction and operand are widened to i64
10 ; instead of truncating IV before its use in the i32 compare instruction.
12 @idx = common global i32 0, align 4
13 @e = common global i32 0, align 4
14 @ptr = common global i32* null, align 8
17 define i32 @test1() {
18 ; CHECK-LABEL: @test1(
19 ; CHECK-NEXT:  entry:
20 ; CHECK-NEXT:    store i32 -1, i32* @idx, align 4
21 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* @e, align 4
22 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP0]], 0
23 ; CHECK-NEXT:    br i1 [[CMP4]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY_LR_PH:%.*]]
24 ; CHECK:       for.body.lr.ph:
25 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32*, i32** @ptr, align 8
26 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* @e, align 4
27 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP2]], i32 0)
28 ; CHECK-NEXT:    [[TMP3:%.*]] = add nuw i32 [[SMAX]], 1
29 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP3]] to i64
30 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
31 ; CHECK:       for.cond:
32 ; CHECK-NEXT:    [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV:%.*]], 1
33 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
34 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_COND_FOR_END_LOOPEXIT_CRIT_EDGE:%.*]]
35 ; CHECK:       for.body:
36 ; CHECK-NEXT:    [[INDVARS_IV]] = phi i64 [ [[INDVARS_IV_NEXT]], [[FOR_COND:%.*]] ], [ 0, [[FOR_BODY_LR_PH]] ]
37 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 [[INDVARS_IV]]
38 ; CHECK-NEXT:    [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
39 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[TMP4]], 0
40 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_COND]]
41 ; CHECK:       if.then:
42 ; CHECK-NEXT:    [[I_05_LCSSA_WIDE:%.*]] = phi i64 [ [[INDVARS_IV]], [[FOR_BODY]] ]
43 ; CHECK-NEXT:    [[TMP5:%.*]] = trunc i64 [[I_05_LCSSA_WIDE]] to i32
44 ; CHECK-NEXT:    store i32 [[TMP5]], i32* @idx, align 4
45 ; CHECK-NEXT:    br label [[FOR_END:%.*]]
46 ; CHECK:       for.cond.for.end.loopexit_crit_edge:
47 ; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT]]
48 ; CHECK:       for.end.loopexit:
49 ; CHECK-NEXT:    br label [[FOR_END]]
50 ; CHECK:       for.end:
51 ; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* @idx, align 4
52 ; CHECK-NEXT:    ret i32 [[TMP6]]
54 entry:
55   store i32 -1, i32* @idx, align 4
56   %0 = load i32, i32* @e, align 4
57   %cmp4 = icmp slt i32 %0, 0
58   br i1 %cmp4, label %for.end.loopexit, label %for.body.lr.ph
60 for.body.lr.ph:
61   %1 = load i32*, i32** @ptr, align 8
62   %2 = load i32, i32* @e, align 4
63   br label %for.body
65 for.cond:
66   %inc = add nsw i32 %i.05, 1
67   %cmp = icmp slt i32 %i.05, %2
68   br i1 %cmp, label %for.body, label %for.cond.for.end.loopexit_crit_edge
70 for.body:
71   %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.cond ]
72   %idxprom = sext i32 %i.05 to i64
73   %arrayidx = getelementptr inbounds i32, i32* %1, i64 %idxprom
74   %3 = load i32, i32* %arrayidx, align 4
75   %tobool = icmp eq i32 %3, 0
76   br i1 %tobool, label %if.then, label %for.cond
78 if.then:
79   %i.05.lcssa = phi i32 [ %i.05, %for.body ]
80   store i32 %i.05.lcssa, i32* @idx, align 4
81   br label %for.end
83 for.cond.for.end.loopexit_crit_edge:
84   br label %for.end.loopexit
86 for.end.loopexit:
87   br label %for.end
89 for.end:
90   %4 = load i32, i32* @idx, align 4
91   ret i32 %4
95 define void @test2([8 x i8]* %a, i8* %b, i8 %limit) {
96 ; CHECK-LABEL: @test2(
97 ; CHECK-NEXT:  entry:
98 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[LIMIT:%.*]] to i32
99 ; CHECK-NEXT:    br i1 undef, label [[FOR_COND1_PREHEADER_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
100 ; CHECK:       for.cond1.preheader.us.preheader:
101 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[CONV]], i32 1)
102 ; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
103 ; CHECK:       for.cond1.preheader.preheader:
104 ; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER:%.*]]
105 ; CHECK:       for.cond1.preheader.us:
106 ; CHECK-NEXT:    [[INDVARS_IV2:%.*]] = phi i64 [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ], [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC13_US:%.*]] ]
107 ; CHECK-NEXT:    br i1 true, label [[FOR_BODY4_LR_PH_US:%.*]], label [[FOR_INC13_US]]
108 ; CHECK:       for.inc13.us.loopexit:
109 ; CHECK-NEXT:    br label [[FOR_INC13_US]]
110 ; CHECK:       for.inc13.us:
111 ; CHECK-NEXT:    [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1
112 ; CHECK-NEXT:    [[EXITCOND4:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT3]], 4
113 ; CHECK-NEXT:    br i1 [[EXITCOND4]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_END_LOOPEXIT1:%.*]]
114 ; CHECK:       for.body4.us:
115 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[FOR_BODY4_LR_PH_US]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY4_US:%.*]] ]
116 ; CHECK-NEXT:    [[ARRAYIDX6_US:%.*]] = getelementptr inbounds [8 x i8], [8 x i8]* [[A:%.*]], i64 [[INDVARS_IV2]], i64 [[INDVARS_IV]]
117 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, i8* [[ARRAYIDX6_US]], align 1
118 ; CHECK-NEXT:    [[IDXPROM7_US:%.*]] = zext i8 [[TMP0]] to i64
119 ; CHECK-NEXT:    [[ARRAYIDX8_US:%.*]] = getelementptr inbounds i8, i8* [[B:%.*]], i64 [[IDXPROM7_US]]
120 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, i8* [[ARRAYIDX8_US]], align 1
121 ; CHECK-NEXT:    store i8 [[TMP1]], i8* [[ARRAYIDX6_US]], align 1
122 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
123 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT:%.*]]
124 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY4_US]], label [[FOR_INC13_US_LOOPEXIT:%.*]]
125 ; CHECK:       for.body4.lr.ph.us:
126 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT]] = zext i32 [[SMAX]] to i64
127 ; CHECK-NEXT:    br label [[FOR_BODY4_US]]
128 ; CHECK:       for.cond1.preheader:
129 ; CHECK-NEXT:    br i1 false, label [[FOR_INC13:%.*]], label [[FOR_INC13]]
130 ; CHECK:       for.inc13:
131 ; CHECK-NEXT:    br i1 false, label [[FOR_COND1_PREHEADER]], label [[FOR_END_LOOPEXIT:%.*]]
132 ; CHECK:       for.end.loopexit:
133 ; CHECK-NEXT:    br label [[FOR_END:%.*]]
134 ; CHECK:       for.end.loopexit1:
135 ; CHECK-NEXT:    br label [[FOR_END]]
136 ; CHECK:       for.end:
137 ; CHECK-NEXT:    ret void
139 entry:
140   %conv = zext i8 %limit to i32
141   br i1 undef, label %for.cond1.preheader, label %for.cond1.preheader.us
143 for.cond1.preheader.us:
144   %storemerge5.us = phi i32 [ 0, %entry ], [ %inc14.us, %for.inc13.us ]
145   br i1 true, label %for.body4.lr.ph.us, label %for.inc13.us
147 for.inc13.us:
148   %inc14.us = add nsw i32 %storemerge5.us, 1
149   %cmp.us = icmp slt i32 %inc14.us, 4
150   br i1 %cmp.us, label %for.cond1.preheader.us, label %for.end
152 for.body4.us:
153   %storemerge14.us = phi i32 [ 0, %for.body4.lr.ph.us ], [ %inc.us, %for.body4.us ]
154   %idxprom.us = sext i32 %storemerge14.us to i64
155   %arrayidx6.us = getelementptr inbounds [8 x i8], [8 x i8]* %a, i64 %idxprom5.us, i64 %idxprom.us
156   %0 = load i8, i8* %arrayidx6.us, align 1
157   %idxprom7.us = zext i8 %0 to i64
158   %arrayidx8.us = getelementptr inbounds i8, i8* %b, i64 %idxprom7.us
159   %1 = load i8, i8* %arrayidx8.us, align 1
160   store i8 %1, i8* %arrayidx6.us, align 1
161   %inc.us = add nsw i32 %storemerge14.us, 1
162   %cmp2.us = icmp slt i32 %inc.us, %conv
163   br i1 %cmp2.us, label %for.body4.us, label %for.inc13.us
165 for.body4.lr.ph.us:
166   %idxprom5.us = sext i32 %storemerge5.us to i64
167   br label %for.body4.us
169 for.cond1.preheader:
170   %storemerge5 = phi i32 [ 0, %entry ], [ %inc14, %for.inc13 ]
171   br i1 false, label %for.inc13, label %for.inc13
173 for.inc13:
174   %inc14 = add nsw i32 %storemerge5, 1
175   %cmp = icmp slt i32 %inc14, 4
176   br i1 %cmp, label %for.cond1.preheader, label %for.end
178 for.end:
179   ret void
183 define i32 @test3(i32* %a, i32 %b) {
184 ; CHECK-LABEL: @test3(
185 ; CHECK-NEXT:  entry:
186 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B:%.*]], i32 0)
187 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
188 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
189 ; CHECK:       for.cond:
190 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
191 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
192 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
193 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
194 ; CHECK:       for.body:
195 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
196 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
197 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP0]]
198 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
199 ; CHECK-NEXT:    br label [[FOR_COND]]
200 ; CHECK:       for.end:
201 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ]
202 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
204 entry:
205   br label %for.cond
207 for.cond:
208   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
209   %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
210   %cmp = icmp slt i32 %i.0, %b
211   br i1 %cmp, label %for.body, label %for.end
213 for.body:
214   %idxprom = sext i32 %i.0 to i64
215   %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
216   %0 = load i32, i32* %arrayidx, align 4
217   %add = add nsw i32 %sum.0, %0
218   %inc = add nsw i32 %i.0, 1
219   br label %for.cond
221 for.end:
222   ret i32 %sum.0
225 declare i32 @fn1(i8 signext)
227 ; PR21030
229 define i32 @test4(i32 %a) {
230 ; CHECK-LABEL: @test4(
231 ; CHECK-NEXT:  entry:
232 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
233 ; CHECK:       for.body:
234 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 253, [[ENTRY:%.*]] ]
235 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[INDVARS_IV]]
236 ; CHECK-NEXT:    [[CONV3:%.*]] = trunc i32 [[OR]] to i8
237 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @fn1(i8 signext [[CONV3]])
238 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i32 [[INDVARS_IV]], -1
239 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i32 [[INDVARS_IV_NEXT]] to i8
240 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[TMP0]], -14
241 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
242 ; CHECK:       for.end:
243 ; CHECK-NEXT:    ret i32 0
245 entry:
246   br label %for.body
248 for.body:
249   %c.07 = phi i8 [ -3, %entry ], [ %dec, %for.body ]
250   %conv6 = zext i8 %c.07 to i32
251   %or = or i32 %a, %conv6
252   %conv3 = trunc i32 %or to i8
253   %call = call i32 @fn1(i8 signext %conv3)
254   %dec = add i8 %c.07, -1
255   %cmp = icmp sgt i8 %dec, -14
256   br i1 %cmp, label %for.body, label %for.end
258 for.end:
259   ret i32 0
263 define i32 @test5(i32* %a, i32 %b) {
264 ; CHECK-LABEL: @test5(
265 ; CHECK-NEXT:  entry:
266 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[B:%.*]] to i64
267 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
268 ; CHECK:       for.cond:
269 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
270 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
271 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP0]]
272 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
273 ; CHECK:       for.body:
274 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
275 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
276 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]]
277 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw i64 [[INDVARS_IV]], 1
278 ; CHECK-NEXT:    br label [[FOR_COND]]
279 ; CHECK:       for.end:
280 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ]
281 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
283 entry:
284   br label %for.cond
286 for.cond:
287   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
288   %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
289   %cmp = icmp ule i32 %i.0, %b
290   br i1 %cmp, label %for.body, label %for.end
292 for.body:
293   %idxprom = zext i32 %i.0 to i64
294   %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
295   %0 = load i32, i32* %arrayidx, align 4
296   %add = add nsw i32 %sum.0, %0
297   %inc = add nsw i32 %i.0, 1
298   br label %for.cond
300 for.end:
301   ret i32 %sum.0
304 define i32 @test6(i32* %a, i32 %b) {
305 ; CHECK-LABEL: @test6(
306 ; CHECK-NEXT:  entry:
307 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B:%.*]], i32 -1)
308 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[SMAX]], 1
309 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP0]] to i64
310 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
311 ; CHECK:       for.cond:
312 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
313 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
314 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
315 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
316 ; CHECK:       for.body:
317 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
318 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
319 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]]
320 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
321 ; CHECK-NEXT:    br label [[FOR_COND]]
322 ; CHECK:       for.end:
323 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ]
324 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
326 entry:
327   br label %for.cond
329 for.cond:
330   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
331   %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
332   %cmp = icmp sle i32 %i.0, %b
333   br i1 %cmp, label %for.body, label %for.end
335 for.body:
336   %idxprom = zext i32 %i.0 to i64
337   %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
338   %0 = load i32, i32* %arrayidx, align 4
339   %add = add nsw i32 %sum.0, %0
340   %inc = add nsw i32 %i.0, 1
341   br label %for.cond
343 for.end:
344   ret i32 %sum.0
347 define i32 @test7(i32* %a, i32 %b) {
348 ; CHECK-LABEL: @test7(
349 ; CHECK-NEXT:  entry:
350 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[B:%.*]] to i64
351 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 -1)
352 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[SMAX]], 2
353 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP1]] to i64
354 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
355 ; CHECK:       for.cond:
356 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
357 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
358 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP0]]
359 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
360 ; CHECK:       for.body:
361 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
362 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
363 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]]
364 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
365 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
366 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND]], label [[FOR_END]]
367 ; CHECK:       for.end:
368 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
369 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
371 entry:
372   br label %for.cond
374 for.cond:
375   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
376   %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
377   %cmp = icmp ule i32 %i.0, %b
378   br i1 %cmp, label %for.body, label %for.end
380 for.body:
381   %idxprom = sext i32 %i.0 to i64
382   %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
383   %0 = load i32, i32* %arrayidx, align 4
384   %add = add nsw i32 %sum.0, %0
385   %inc = add nsw i32 %i.0, 1
386   %cmp2 = icmp sle i32 %i.0, %b
387   br i1 %cmp2, label %for.cond, label %for.end
389 for.end:
390   ret i32 %sum.0
393 define i32 @test8(i32* %a, i32 %b, i32 %init) {
394 ;     Note: %indvars.iv is the sign extension of %i.0
395 ; CHECK-LABEL: @test8(
396 ; CHECK-NEXT:  entry:
397 ; CHECK-NEXT:    [[E:%.*]] = icmp sgt i32 [[INIT:%.*]], 0
398 ; CHECK-NEXT:    br i1 [[E]], label [[FOR_COND_PREHEADER:%.*]], label [[LEAVE:%.*]]
399 ; CHECK:       for.cond.preheader:
400 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[INIT]] to i64
401 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[B:%.*]] to i64
402 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
403 ; CHECK:       for.cond:
404 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ]
405 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ]
406 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP1]]
407 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
408 ; CHECK:       for.body:
409 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
410 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
411 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]]
412 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
413 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i64 0, [[INDVARS_IV_NEXT]]
414 ; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[FOR_END]]
415 ; CHECK:       for.end:
416 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
417 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
418 ; CHECK:       leave:
419 ; CHECK-NEXT:    ret i32 0
421 entry:
422   %e = icmp sgt i32 %init, 0
423   br i1 %e, label %for.cond, label %leave
425 for.cond:
426   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
427   %i.0 = phi i32 [ %init, %entry ], [ %inc, %for.body ]
428   %cmp = icmp ule i32 %i.0, %b
429   br i1 %cmp, label %for.body, label %for.end
431 for.body:
432   %idxprom = sext i32 %i.0 to i64
433   %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
434   %0 = load i32, i32* %arrayidx, align 4
435   %add = add nsw i32 %sum.0, %0
436   %inc = add nsw i32 %i.0, 1
437   %cmp2 = icmp slt i32 0, %inc
438   br i1 %cmp2, label %for.cond, label %for.end
440 for.end:
441   ret i32 %sum.0
443 leave:
444   ret i32 0
447 define i32 @test9(i32* %a, i32 %b, i32 %init) {
448 ;     Note: %indvars.iv is the zero extension of %i.0
449 ; CHECK-LABEL: @test9(
450 ; CHECK-NEXT:  entry:
451 ; CHECK-NEXT:    [[E:%.*]] = icmp sgt i32 [[INIT:%.*]], 0
452 ; CHECK-NEXT:    br i1 [[E]], label [[FOR_COND_PREHEADER:%.*]], label [[LEAVE:%.*]]
453 ; CHECK:       for.cond.preheader:
454 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[INIT]] to i64
455 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[INIT]], i32 [[B:%.*]])
456 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
457 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
458 ; CHECK:       for.cond:
459 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ]
460 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ]
461 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
462 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
463 ; CHECK:       for.body:
464 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
465 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
466 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]]
467 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
468 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
469 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 0, [[TMP2]]
470 ; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[FOR_END]]
471 ; CHECK:       for.end:
472 ; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
473 ; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
474 ; CHECK:       leave:
475 ; CHECK-NEXT:    ret i32 0
477 entry:
478   %e = icmp sgt i32 %init, 0
479   br i1 %e, label %for.cond, label %leave
481 for.cond:
482   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
483   %i.0 = phi i32 [ %init, %entry ], [ %inc, %for.body ]
484   %cmp = icmp slt i32 %i.0, %b
485   br i1 %cmp, label %for.body, label %for.end
487 for.body:
488   %idxprom = zext i32 %i.0 to i64
489   %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
490   %0 = load i32, i32* %arrayidx, align 4
491   %add = add nsw i32 %sum.0, %0
492   %inc = add nsw i32 %i.0, 1
493   %cmp2 = icmp slt i32 0, %inc
494   br i1 %cmp2, label %for.cond, label %for.end
496 for.end:
497   ret i32 %sum.0
499 leave:
500   ret i32 0
503 declare void @consume.i64(i64)
504 declare void @consume.i1(i1)
506 define i32 @test10(i32 %v) {
507 ; CHECK-LABEL: @test10(
508 ; CHECK-NEXT:  entry:
509 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i32 [[V:%.*]] to i64
510 ; CHECK-NEXT:    br label [[LOOP:%.*]]
511 ; CHECK:       loop:
512 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
513 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
514 ; CHECK-NEXT:    [[TMP0:%.*]] = mul nsw i64 [[INDVARS_IV]], -1
515 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], [[SEXT]]
516 ; CHECK-NEXT:    call void @consume.i1(i1 [[TMP1]])
517 ; CHECK-NEXT:    call void @consume.i64(i64 [[TMP0]])
518 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 11
519 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE:%.*]]
520 ; CHECK:       leave:
521 ; CHECK-NEXT:    ret i32 22
523   entry:
524   br label %loop
526   loop:
528   %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
529   %i.inc = add i32 %i, 1
530   %iv = mul i32 %i, -1
531   %cmp = icmp eq i32 %iv, %v
532   call void @consume.i1(i1 %cmp)
533   %be.cond = icmp slt i32 %i.inc, 11
534   %ext = sext i32 %iv to i64
535   call void @consume.i64(i64 %ext)
536   br i1 %be.cond, label %loop, label %leave
538   leave:
539   ret i32 22
542 ; TODO: We don't really need trunc/zext here because when iv.next overflows,
543 ; its value is not used.
544 define i32 @test11(i32 %start, i32* %p, i32* %q) {
545 ; CHECK-LABEL: @test11(
546 ; CHECK-NEXT:  entry:
547 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
548 ; CHECK-NEXT:    br label [[LOOP:%.*]]
549 ; CHECK:       loop:
550 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
551 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
552 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
553 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
554 ; CHECK:       backedge:
555 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
556 ; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
557 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
558 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
559 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
560 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
561 ; CHECK:       exit:
562 ; CHECK-NEXT:    ret i32 0
563 ; CHECK:       failure:
564 ; CHECK-NEXT:    unreachable
566 entry:
567   br label %loop
569 loop:
570   %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
571   %iv.next = add i32 %iv, -1
572   %cond = icmp eq i32 %iv, 0
573   br i1 %cond, label %exit, label %backedge
575 backedge:
576   %index = zext i32 %iv.next to i64
577   %store.addr = getelementptr i32, i32* %p, i64 %index
578   store i32 1, i32* %store.addr
579   %load.addr = getelementptr i32, i32* %q, i64 %index
580   %stop = load i32, i32* %q
581   %loop.cond = icmp eq i32 %stop, 0
582   br i1 %loop.cond, label %loop, label %failure
584 exit:
585   ret i32 0
587 failure:
588   unreachable
591 define i32 @test12(i32 %start, i32* %p, i32* %q) {
592 ; CHECK-LABEL: @test12(
593 ; CHECK-NEXT:  entry:
594 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
595 ; CHECK-NEXT:    br label [[LOOP:%.*]]
596 ; CHECK:       loop:
597 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
598 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
599 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
600 ; CHECK:       backedge:
601 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
602 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
603 ; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
604 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
605 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
606 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
607 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
608 ; CHECK:       exit:
609 ; CHECK-NEXT:    ret i32 0
610 ; CHECK:       failure:
611 ; CHECK-NEXT:    unreachable
613 entry:
614   br label %loop
616 loop:
617   %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
618   %cond = icmp eq i32 %iv, 0
619   br i1 %cond, label %exit, label %backedge
621 backedge:
622   %iv.next = add i32 %iv, -1
623   %index = zext i32 %iv.next to i64
624   %store.addr = getelementptr i32, i32* %p, i64 %index
625   store i32 1, i32* %store.addr
626   %load.addr = getelementptr i32, i32* %q, i64 %index
627   %stop = load i32, i32* %q
628   %loop.cond = icmp eq i32 %stop, 0
629   br i1 %loop.cond, label %loop, label %failure
631 exit:
632   ret i32 0
634 failure:
635   unreachable
638 define i32 @test13(i32 %start, i32* %p, i32* %q) {
639 ; CHECK-LABEL: @test13(
640 ; CHECK-NEXT:  entry:
641 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
642 ; CHECK-NEXT:    br label [[LOOP:%.*]]
643 ; CHECK:       loop:
644 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
645 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
646 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
647 ; CHECK:       backedge:
648 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
649 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
650 ; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
651 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
652 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
653 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
654 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
655 ; CHECK:       exit:
656 ; CHECK-NEXT:    ret i32 0
657 ; CHECK:       failure:
658 ; CHECK-NEXT:    unreachable
660 entry:
661   br label %loop
663 loop:
664   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
665   %cond = icmp eq i32 %iv, 0
666   br i1 %cond, label %exit, label %backedge
668 backedge:
669   %foo = add i32 %iv, -1
670   %index = zext i32 %foo to i64
671   %store.addr = getelementptr i32, i32* %p, i64 %index
672   store i32 1, i32* %store.addr
673   %load.addr = getelementptr i32, i32* %q, i64 %index
674   %stop = load i32, i32* %q
675   %loop.cond = icmp eq i32 %stop, 0
676   %iv.next.1 = add i32 %iv, -1
677   br i1 %loop.cond, label %loop, label %failure
679 exit:
680   ret i32 0
682 failure:
683   unreachable
686 define i32 @test14(i32 %start, i32* %p, i32* %q) {
687 ; CHECK-LABEL: @test14(
688 ; CHECK-NEXT:  entry:
689 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
690 ; CHECK-NEXT:    br label [[LOOP:%.*]]
691 ; CHECK:       loop:
692 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
693 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
694 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
695 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
696 ; CHECK:       backedge:
697 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
698 ; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
699 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
700 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
701 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
702 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
703 ; CHECK:       exit:
704 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
705 ; CHECK-NEXT:    ret i32 [[TMP2]]
706 ; CHECK:       failure:
707 ; CHECK-NEXT:    unreachable
709 entry:
710   br label %loop
712 loop:
713   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
714   %cond = icmp eq i32 %iv, 0
715   %foo = add i32 %iv, -1
716   br i1 %cond, label %exit, label %backedge
718 backedge:
719   %index = zext i32 %foo to i64
720   %store.addr = getelementptr i32, i32* %p, i64 %index
721   store i32 1, i32* %store.addr
722   %load.addr = getelementptr i32, i32* %q, i64 %index
723   %stop = load i32, i32* %q
724   %loop.cond = icmp eq i32 %stop, 0
725   %iv.next.1 = add i32 %iv, -1
726   br i1 %loop.cond, label %loop, label %failure
728 exit:
729   ret i32 %foo
731 failure:
732   unreachable
735 declare void @test14a-callee(i1 %cond)
737 ; Same as @test14 but with unwind exit.
738 ; Trunc instructions must be added below the landing pad.
739 define i32 @test14a(i32 %start, i32* %p, i32* %q, i1 %c) personality i1 1 {
740 ; CHECK-LABEL: @test14a(
741 ; CHECK-NEXT:  entry:
742 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
743 ; CHECK-NEXT:    br label [[LOOP:%.*]]
744 ; CHECK:       loop:
745 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
746 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
747 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
748 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
749 ; CHECK:       backedge:
750 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
751 ; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
752 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
753 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
754 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
755 ; CHECK-NEXT:    invoke void @test14a-callee(i1 [[LOOP_COND]])
756 ; CHECK-NEXT:    to label [[LOOP]] unwind label [[EXCEPTION:%.*]]
757 ; CHECK:       exit:
758 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
759 ; CHECK-NEXT:    ret i32 [[TMP2]]
760 ; CHECK:       exception:
761 ; CHECK-NEXT:    [[FOO_LCSSA1_WIDE:%.*]] = phi i64 [ [[TMP1]], [[BACKEDGE]] ]
762 ; CHECK-NEXT:    [[TMP3:%.*]] = landingpad i1
763 ; CHECK-NEXT:    cleanup
764 ; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 [[FOO_LCSSA1_WIDE]] to i32
765 ; CHECK-NEXT:    ret i32 [[TMP4]]
767 entry:
768   br label %loop
770 loop:
771   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
772   %cond = icmp eq i32 %iv, 0
773   %foo = add i32 %iv, -1
774   br i1 %cond, label %exit, label %backedge
776 backedge:
777   %index = zext i32 %foo to i64
778   %store.addr = getelementptr i32, i32* %p, i64 %index
779   store i32 1, i32* %store.addr
780   %load.addr = getelementptr i32, i32* %q, i64 %index
781   %stop = load i32, i32* %q
782   %loop.cond = icmp eq i32 %stop, 0
783   %iv.next.1 = add i32 %iv, -1
784   invoke void @test14a-callee(i1 %loop.cond) to label %loop unwind label %exception
786 exit:
787   ret i32 %foo
789 exception:
790   landingpad i1
791   cleanup
792   ret i32 %foo
795 declare void @use(i32 %arg)
797 define i32 @test15(i32 %start, i32* %p, i32* %q) {
798 ; CHECK-LABEL: @test15(
799 ; CHECK-NEXT:  entry:
800 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
801 ; CHECK-NEXT:    br label [[LOOP:%.*]]
802 ; CHECK:       loop:
803 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
804 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
805 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
806 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
807 ; CHECK:       backedge:
808 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
809 ; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
810 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
811 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
812 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
813 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
814 ; CHECK:       exit:
815 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
816 ; CHECK-NEXT:    call void @use(i32 [[TMP2]])
817 ; CHECK-NEXT:    ret i32 [[TMP2]]
818 ; CHECK:       failure:
819 ; CHECK-NEXT:    [[FOO_LCSSA1_WIDE:%.*]] = phi i64 [ [[TMP1]], [[BACKEDGE]] ]
820 ; CHECK-NEXT:    [[TMP3:%.*]] = trunc i64 [[FOO_LCSSA1_WIDE]] to i32
821 ; CHECK-NEXT:    call void @use(i32 [[TMP3]])
822 ; CHECK-NEXT:    unreachable
824 entry:
825   br label %loop
827 loop:
828   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
829   %cond = icmp eq i32 %iv, 0
830   %foo = add i32 %iv, -1
831   br i1 %cond, label %exit, label %backedge
833 backedge:
834   %index = zext i32 %foo to i64
835   %store.addr = getelementptr i32, i32* %p, i64 %index
836   store i32 1, i32* %store.addr
837   %load.addr = getelementptr i32, i32* %q, i64 %index
838   %stop = load i32, i32* %q
839   %loop.cond = icmp eq i32 %stop, 0
840   %iv.next.1 = add i32 %iv, -1
841   br i1 %loop.cond, label %loop, label %failure
843 exit:
844   call void @use(i32 %foo)
845   ret i32 %foo
847 failure:
848   call void @use(i32 %foo)
849   unreachable
852 define i32 @test16_unsigned_pos1(i32 %start, i32* %p, i32* %q, i32 %x) {
853 ; CHECK-LABEL: @test16_unsigned_pos1(
854 ; CHECK-NEXT:  entry:
855 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
856 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[TMP0]], -1
857 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[X:%.*]] to i64
858 ; CHECK-NEXT:    br label [[LOOP:%.*]]
859 ; CHECK:       loop:
860 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
861 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
862 ; CHECK-NEXT:    [[TMP3:%.*]] = add nsw i64 [[INDVARS_IV]], -1
863 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
864 ; CHECK:       guarded:
865 ; CHECK-NEXT:    [[ICMP_USER_WIDE4:%.*]] = icmp ult i64 [[TMP1]], [[TMP2]]
866 ; CHECK-NEXT:    br i1 [[ICMP_USER_WIDE4]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
867 ; CHECK:       backedge:
868 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP3]]
869 ; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
870 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
871 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
872 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
873 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
874 ; CHECK:       exit:
875 ; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 -1 to i32
876 ; CHECK-NEXT:    call void @use(i32 [[TMP4]])
877 ; CHECK-NEXT:    ret i32 [[TMP4]]
878 ; CHECK:       failure:
879 ; CHECK-NEXT:    [[FOO_LCSSA2_WIDE:%.*]] = phi i64 [ [[TMP3]], [[BACKEDGE]] ]
880 ; CHECK-NEXT:    [[TMP5:%.*]] = trunc i64 [[FOO_LCSSA2_WIDE]] to i32
881 ; CHECK-NEXT:    call void @use(i32 [[TMP5]])
882 ; CHECK-NEXT:    unreachable
883 ; CHECK:       side_exit:
884 ; CHECK-NEXT:    ret i32 0
886 entry:
887   br label %loop
889 loop:
890   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
891   %cond = icmp eq i32 %iv, 0
892   %foo = add i32 %iv, -1
893   br i1 %cond, label %exit, label %guarded
895 guarded:
896   %icmp_user = icmp ult i32 %foo, %x
897   br i1 %icmp_user, label %backedge, label %side_exit
899 backedge:
900   %index = zext i32 %foo to i64
901   %store.addr = getelementptr i32, i32* %p, i64 %index
902   store i32 1, i32* %store.addr
903   %load.addr = getelementptr i32, i32* %q, i64 %index
904   %stop = load i32, i32* %q
905   %loop.cond = icmp eq i32 %stop, 0
906   %iv.next.1 = add i32 %iv, -1
907   br i1 %loop.cond, label %loop, label %failure
909 exit:
910   call void @use(i32 %foo)
911   ret i32 %foo
913 failure:
914   call void @use(i32 %foo)
915   unreachable
917 side_exit:
918   ret i32 0
921 ; TODO: We can widen here despite the icmp user of %foo in guarded block.
922 define i32 @test16_unsigned_pos2(i32 %start, i32* %p, i32* %q, i32 %x) {
923 ; CHECK-LABEL: @test16_unsigned_pos2(
924 ; CHECK-NEXT:  entry:
925 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
926 ; CHECK-NEXT:    br label [[LOOP:%.*]]
927 ; CHECK:       loop:
928 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
929 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
930 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[INDVARS_IV]] to i32
931 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[TMP1]], -1
932 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
933 ; CHECK:       guarded:
934 ; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp ne i32 [[FOO]], [[X:%.*]]
935 ; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
936 ; CHECK:       backedge:
937 ; CHECK-NEXT:    [[INDEX:%.*]] = zext i32 [[FOO]] to i64
938 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[INDEX]]
939 ; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
940 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 [[INDEX]]
941 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q]], align 4
942 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
943 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
944 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
945 ; CHECK:       exit:
946 ; CHECK-NEXT:    call void @use(i32 -1)
947 ; CHECK-NEXT:    ret i32 -1
948 ; CHECK:       failure:
949 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
950 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
951 ; CHECK-NEXT:    unreachable
952 ; CHECK:       side_exit:
953 ; CHECK-NEXT:    ret i32 0
955 entry:
956   br label %loop
958 loop:
959   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
960   %cond = icmp eq i32 %iv, 0
961   %foo = add i32 %iv, -1
962   br i1 %cond, label %exit, label %guarded
964 guarded:
965   %icmp_user = icmp ne i32 %foo, %x
966   br i1 %icmp_user, label %backedge, label %side_exit
968 backedge:
969   %index = zext i32 %foo to i64
970   %store.addr = getelementptr i32, i32* %p, i64 %index
971   store i32 1, i32* %store.addr
972   %load.addr = getelementptr i32, i32* %q, i64 %index
973   %stop = load i32, i32* %q
974   %loop.cond = icmp eq i32 %stop, 0
975   %iv.next.1 = add i32 %iv, -1
976   br i1 %loop.cond, label %loop, label %failure
978 exit:
979   call void @use(i32 %foo)
980   ret i32 %foo
982 failure:
983   call void @use(i32 %foo)
984   unreachable
986 side_exit:
987   ret i32 0
990 ; icmp slt user in guarded block prevents widening.
991 define i32 @test16_unsigned_neg(i32 %start, i32* %p, i32* %q, i32 %x) {
992 ; CHECK-LABEL: @test16_unsigned_neg(
993 ; CHECK-NEXT:  entry:
994 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
995 ; CHECK-NEXT:    br label [[LOOP:%.*]]
996 ; CHECK:       loop:
997 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
998 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
999 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[INDVARS_IV]] to i32
1000 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[TMP1]], -1
1001 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1002 ; CHECK:       guarded:
1003 ; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp slt i32 [[FOO]], [[X:%.*]]
1004 ; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1005 ; CHECK:       backedge:
1006 ; CHECK-NEXT:    [[INDEX:%.*]] = zext i32 [[FOO]] to i64
1007 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[INDEX]]
1008 ; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
1009 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 [[INDEX]]
1010 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q]], align 4
1011 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1012 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
1013 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1014 ; CHECK:       exit:
1015 ; CHECK-NEXT:    call void @use(i32 -1)
1016 ; CHECK-NEXT:    ret i32 -1
1017 ; CHECK:       failure:
1018 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1019 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1020 ; CHECK-NEXT:    unreachable
1021 ; CHECK:       side_exit:
1022 ; CHECK-NEXT:    ret i32 0
1024 entry:
1025   br label %loop
1027 loop:
1028   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1029   %cond = icmp eq i32 %iv, 0
1030   %foo = add i32 %iv, -1
1031   br i1 %cond, label %exit, label %guarded
1033 guarded:
1034   %icmp_user = icmp slt i32 %foo, %x
1035   br i1 %icmp_user, label %backedge, label %side_exit
1037 backedge:
1038   %index = zext i32 %foo to i64
1039   %store.addr = getelementptr i32, i32* %p, i64 %index
1040   store i32 1, i32* %store.addr
1041   %load.addr = getelementptr i32, i32* %q, i64 %index
1042   %stop = load i32, i32* %q
1043   %loop.cond = icmp eq i32 %stop, 0
1044   %iv.next.1 = add i32 %iv, -1
1045   br i1 %loop.cond, label %loop, label %failure
1047 exit:
1048   call void @use(i32 %foo)
1049   ret i32 %foo
1051 failure:
1052   call void @use(i32 %foo)
1053   unreachable
1055 side_exit:
1056   ret i32 0
1059 ; TODO: We can widen here despite the icmp user of %foo in guarded block.
1060 define i32 @test16_signed_pos1(i32 %start, i32* %p, i32* %q, i32 %x) {
1061 ; CHECK-LABEL: @test16_signed_pos1(
1062 ; CHECK-NEXT:  entry:
1063 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1064 ; CHECK:       loop:
1065 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT_1:%.*]], [[BACKEDGE:%.*]] ]
1066 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[IV]], 0
1067 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[IV]], -1
1068 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1069 ; CHECK:       guarded:
1070 ; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp slt i32 [[FOO]], [[X:%.*]]
1071 ; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1072 ; CHECK:       backedge:
1073 ; CHECK-NEXT:    [[INDEX:%.*]] = sext i32 [[FOO]] to i64
1074 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[INDEX]]
1075 ; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
1076 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 [[INDEX]]
1077 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q]], align 4
1078 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1079 ; CHECK-NEXT:    [[IV_NEXT_1]] = add i32 [[IV]], -1
1080 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1081 ; CHECK:       exit:
1082 ; CHECK-NEXT:    call void @use(i32 -1)
1083 ; CHECK-NEXT:    ret i32 -1
1084 ; CHECK:       failure:
1085 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1086 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1087 ; CHECK-NEXT:    unreachable
1088 ; CHECK:       side_exit:
1089 ; CHECK-NEXT:    ret i32 0
1091 entry:
1092   br label %loop
1094 loop:
1095   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1096   %cond = icmp eq i32 %iv, 0
1097   %foo = add i32 %iv, -1
1098   br i1 %cond, label %exit, label %guarded
1100 guarded:
1101   %icmp_user = icmp slt i32 %foo, %x
1102   br i1 %icmp_user, label %backedge, label %side_exit
1104 backedge:
1105   %index = sext i32 %foo to i64
1106   %store.addr = getelementptr i32, i32* %p, i64 %index
1107   store i32 1, i32* %store.addr
1108   %load.addr = getelementptr i32, i32* %q, i64 %index
1109   %stop = load i32, i32* %q
1110   %loop.cond = icmp eq i32 %stop, 0
1111   %iv.next.1 = add i32 %iv, -1
1112   br i1 %loop.cond, label %loop, label %failure
1114 exit:
1115   call void @use(i32 %foo)
1116   ret i32 %foo
1118 failure:
1119   call void @use(i32 %foo)
1120   unreachable
1122 side_exit:
1123   ret i32 0
1126 ; TODO: We can widen here despite the icmp user of %foo in guarded block.
1127 define i32 @test16_signed_pos2(i32 %start, i32* %p, i32* %q, i32 %x) {
1128 ; CHECK-LABEL: @test16_signed_pos2(
1129 ; CHECK-NEXT:  entry:
1130 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1131 ; CHECK:       loop:
1132 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT_1:%.*]], [[BACKEDGE:%.*]] ]
1133 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[IV]], 0
1134 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[IV]], -1
1135 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1136 ; CHECK:       guarded:
1137 ; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp ne i32 [[FOO]], [[X:%.*]]
1138 ; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1139 ; CHECK:       backedge:
1140 ; CHECK-NEXT:    [[INDEX:%.*]] = sext i32 [[FOO]] to i64
1141 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[INDEX]]
1142 ; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
1143 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 [[INDEX]]
1144 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q]], align 4
1145 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1146 ; CHECK-NEXT:    [[IV_NEXT_1]] = add i32 [[IV]], -1
1147 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1148 ; CHECK:       exit:
1149 ; CHECK-NEXT:    call void @use(i32 -1)
1150 ; CHECK-NEXT:    ret i32 -1
1151 ; CHECK:       failure:
1152 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1153 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1154 ; CHECK-NEXT:    unreachable
1155 ; CHECK:       side_exit:
1156 ; CHECK-NEXT:    ret i32 0
1158 entry:
1159   br label %loop
1161 loop:
1162   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1163   %cond = icmp eq i32 %iv, 0
1164   %foo = add i32 %iv, -1
1165   br i1 %cond, label %exit, label %guarded
1167 guarded:
1168   %icmp_user = icmp ne i32 %foo, %x
1169   br i1 %icmp_user, label %backedge, label %side_exit
1171 backedge:
1172   %index = sext i32 %foo to i64
1173   %store.addr = getelementptr i32, i32* %p, i64 %index
1174   store i32 1, i32* %store.addr
1175   %load.addr = getelementptr i32, i32* %q, i64 %index
1176   %stop = load i32, i32* %q
1177   %loop.cond = icmp eq i32 %stop, 0
1178   %iv.next.1 = add i32 %iv, -1
1179   br i1 %loop.cond, label %loop, label %failure
1181 exit:
1182   call void @use(i32 %foo)
1183   ret i32 %foo
1185 failure:
1186   call void @use(i32 %foo)
1187   unreachable
1189 side_exit:
1190   ret i32 0
1193 ; icmp ult user in guarded block prevents widening.
1194 define i32 @test16_signed_neg(i32 %start, i32* %p, i32* %q, i32 %x) {
1195 ; CHECK-LABEL: @test16_signed_neg(
1196 ; CHECK-NEXT:  entry:
1197 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[START:%.*]], -1
1198 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1199 ; CHECK:       loop:
1200 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START]], [[ENTRY:%.*]] ], [ [[IV_NEXT_1:%.*]], [[BACKEDGE:%.*]] ]
1201 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[IV]], 0
1202 ; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[IV]], -1
1203 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1204 ; CHECK:       guarded:
1205 ; CHECK-NEXT:    [[ICMP_USER3:%.*]] = icmp ult i32 [[TMP0]], [[X:%.*]]
1206 ; CHECK-NEXT:    br i1 [[ICMP_USER3]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1207 ; CHECK:       backedge:
1208 ; CHECK-NEXT:    [[INDEX:%.*]] = sext i32 [[FOO]] to i64
1209 ; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[INDEX]]
1210 ; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
1211 ; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 [[INDEX]]
1212 ; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q]], align 4
1213 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1214 ; CHECK-NEXT:    [[IV_NEXT_1]] = add i32 [[IV]], -1
1215 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1216 ; CHECK:       exit:
1217 ; CHECK-NEXT:    call void @use(i32 -1)
1218 ; CHECK-NEXT:    ret i32 -1
1219 ; CHECK:       failure:
1220 ; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1221 ; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1222 ; CHECK-NEXT:    unreachable
1223 ; CHECK:       side_exit:
1224 ; CHECK-NEXT:    ret i32 0
1226 entry:
1227   br label %loop
1229 loop:
1230   %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1231   %cond = icmp eq i32 %iv, 0
1232   %foo = add i32 %iv, -1
1233   br i1 %cond, label %exit, label %guarded
1235 guarded:
1236   %icmp_user = icmp ult i32 %foo, %x
1237   br i1 %icmp_user, label %backedge, label %side_exit
1239 backedge:
1240   %index = sext i32 %foo to i64
1241   %store.addr = getelementptr i32, i32* %p, i64 %index
1242   store i32 1, i32* %store.addr
1243   %load.addr = getelementptr i32, i32* %q, i64 %index
1244   %stop = load i32, i32* %q
1245   %loop.cond = icmp eq i32 %stop, 0
1246   %iv.next.1 = add i32 %iv, -1
1247   br i1 %loop.cond, label %loop, label %failure
1249 exit:
1250   call void @use(i32 %foo)
1251   ret i32 %foo
1253 failure:
1254   call void @use(i32 %foo)
1255   unreachable
1257 side_exit:
1258   ret i32 0
1261 define i32 @test17(i32* %p, i32 %len) {
1262 ; CHECK-LABEL: @test17(
1263 ; CHECK-NEXT:  entry:
1264 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[LEN:%.*]] to i64
1265 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1266 ; CHECK:       loop:
1267 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
1268 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
1269 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
1270 ; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
1271 ; CHECK:       backedge:
1272 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 [[TMP1]]
1273 ; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, i32* [[ADDR]] unordered, align 4
1274 ; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], 0
1275 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
1276 ; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
1277 ; CHECK:       exit:
1278 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
1279 ; CHECK-NEXT:    ret i32 [[TMP2]]
1280 ; CHECK:       failure:
1281 ; CHECK-NEXT:    unreachable
1283 entry:
1284   br label %loop
1286 loop:
1287   %iv = phi i32 [ %iv.next, %backedge ], [ %len, %entry ]
1288   %iv.next = add i32 %iv, -1
1289   %cond_1 = icmp eq i32 %iv, 0
1290   br i1 %cond_1, label %exit, label %backedge
1292 backedge:
1293   %iv.next.wide = zext i32 %iv.next to i64
1294   %addr = getelementptr inbounds i32, i32* %p, i64 %iv.next.wide
1295   %loaded = load atomic i32, i32* %addr unordered, align 4
1296   %cond_2 = icmp eq i32 %loaded, 0
1297   br i1 %cond_2, label %failure, label %loop
1299 exit:
1300   ret i32 %iv.next
1302 failure:
1303   unreachable