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
4target triple = "aarch64--linux-gnu"
5
6; Provide legal integer types.
7target datalayout = "n8:16:32:64"
8
9
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.
12
13@idx = common global i32 0, align 4
14@e = common global i32 0, align 4
15@ptr = common global i32* null, align 8
16
17
18define i32 @test1() {
19; CHECK-LABEL: @test1(
20; CHECK-NEXT:  entry:
21; CHECK-NEXT:    store i32 -1, i32* @idx, align 4
22; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* @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 i32*, i32** @ptr, align 8
27; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* @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, i32* [[TMP1]], i64 [[INDVARS_IV]]
39; CHECK-NEXT:    [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
40; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[TMP4]], 0
41; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_COND]]
42; CHECK:       if.then:
43; CHECK-NEXT:    [[I_05_LCSSA_WIDE:%.*]] = phi i64 [ [[INDVARS_IV]], [[FOR_BODY]] ]
44; CHECK-NEXT:    [[TMP5:%.*]] = trunc i64 [[I_05_LCSSA_WIDE]] to i32
45; CHECK-NEXT:    store i32 [[TMP5]], i32* @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, i32* @idx, align 4
53; CHECK-NEXT:    ret i32 [[TMP6]]
54;
55entry:
56  store i32 -1, i32* @idx, align 4
57  %0 = load i32, i32* @e, align 4
58  %cmp4 = icmp slt i32 %0, 0
59  br i1 %cmp4, label %for.end.loopexit, label %for.body.lr.ph
60
61for.body.lr.ph:
62  %1 = load i32*, i32** @ptr, align 8
63  %2 = load i32, i32* @e, align 4
64  br label %for.body
65
66for.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
70
71for.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, i32* %1, i64 %idxprom
75  %3 = load i32, i32* %arrayidx, align 4
76  %tobool = icmp eq i32 %3, 0
77  br i1 %tobool, label %if.then, label %for.cond
78
79if.then:
80  %i.05.lcssa = phi i32 [ %i.05, %for.body ]
81  store i32 %i.05.lcssa, i32* @idx, align 4
82  br label %for.end
83
84for.cond.for.end.loopexit_crit_edge:
85  br label %for.end.loopexit
86
87for.end.loopexit:
88  br label %for.end
89
90for.end:
91  %4 = load i32, i32* @idx, align 4
92  ret i32 %4
93}
94
95
96define void @test2([8 x i8]* %a, i8* %b, i8 %limit) {
97; CHECK-LABEL: @test2(
98; CHECK-NEXT:  entry:
99; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[LIMIT:%.*]] to i32
100; CHECK-NEXT:    br i1 undef, label [[FOR_COND1_PREHEADER_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
101; CHECK:       for.cond1.preheader.us.preheader:
102; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[CONV]], i32 1)
103; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
104; CHECK:       for.cond1.preheader.preheader:
105; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER:%.*]]
106; CHECK:       for.cond1.preheader.us:
107; CHECK-NEXT:    [[INDVARS_IV3:%.*]] = phi i64 [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ], [ [[INDVARS_IV_NEXT4:%.*]], [[FOR_INC13_US:%.*]] ]
108; CHECK-NEXT:    br i1 true, label [[FOR_BODY4_LR_PH_US:%.*]], label [[FOR_INC13_US]]
109; CHECK:       for.inc13.us.loopexit:
110; CHECK-NEXT:    br label [[FOR_INC13_US]]
111; CHECK:       for.inc13.us:
112; CHECK-NEXT:    [[INDVARS_IV_NEXT4]] = add nuw nsw i64 [[INDVARS_IV3]], 1
113; CHECK-NEXT:    [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT4]], 4
114; CHECK-NEXT:    br i1 [[EXITCOND6]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_END_LOOPEXIT1:%.*]]
115; CHECK:       for.body4.us:
116; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[FOR_BODY4_LR_PH_US]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY4_US:%.*]] ]
117; CHECK-NEXT:    [[ARRAYIDX6_US:%.*]] = getelementptr inbounds [8 x i8], [8 x i8]* [[A:%.*]], i64 [[INDVARS_IV3]], i64 [[INDVARS_IV]]
118; CHECK-NEXT:    [[TMP0:%.*]] = load i8, i8* [[ARRAYIDX6_US]], align 1
119; CHECK-NEXT:    [[IDXPROM7_US:%.*]] = zext i8 [[TMP0]] to i64
120; CHECK-NEXT:    [[ARRAYIDX8_US:%.*]] = getelementptr inbounds i8, i8* [[B:%.*]], i64 [[IDXPROM7_US]]
121; CHECK-NEXT:    [[TMP1:%.*]] = load i8, i8* [[ARRAYIDX8_US]], align 1
122; CHECK-NEXT:    store i8 [[TMP1]], i8* [[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
139;
140entry:
141  %conv = zext i8 %limit to i32
142  br i1 undef, label %for.cond1.preheader, label %for.cond1.preheader.us
143
144for.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
147
148for.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
152
153for.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], [8 x i8]* %a, i64 %idxprom5.us, i64 %idxprom.us
157  %0 = load i8, i8* %arrayidx6.us, align 1
158  %idxprom7.us = zext i8 %0 to i64
159  %arrayidx8.us = getelementptr inbounds i8, i8* %b, i64 %idxprom7.us
160  %1 = load i8, i8* %arrayidx8.us, align 1
161  store i8 %1, i8* %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
165
166for.body4.lr.ph.us:
167  %idxprom5.us = sext i32 %storemerge5.us to i64
168  br label %for.body4.us
169
170for.cond1.preheader:
171  %storemerge5 = phi i32 [ 0, %entry ], [ %inc14, %for.inc13 ]
172  br i1 false, label %for.inc13, label %for.inc13
173
174for.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
178
179for.end:
180  ret void
181}
182
183
184define i32 @test3(i32* %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, i32* [[A:%.*]], i64 [[INDVARS_IV]]
197; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[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]]
204;
205entry:
206  br label %for.cond
207
208for.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
213
214for.body:
215  %idxprom = sext i32 %i.0 to i64
216  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
217  %0 = load i32, i32* %arrayidx, align 4
218  %add = add nsw i32 %sum.0, %0
219  %inc = add nsw i32 %i.0, 1
220  br label %for.cond
221
222for.end:
223  ret i32 %sum.0
224}
225
226declare i32 @fn1(i8 signext)
227
228; PR21030
229
230define i32 @test4(i32 %a) {
231; CHECK-LABEL: @test4(
232; CHECK-NEXT:  entry:
233; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
234; CHECK:       for.body:
235; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 253, [[ENTRY:%.*]] ]
236; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[INDVARS_IV]]
237; CHECK-NEXT:    [[CONV3:%.*]] = trunc i32 [[OR]] to i8
238; CHECK-NEXT:    [[CALL:%.*]] = call i32 @fn1(i8 signext [[CONV3]])
239; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i32 [[INDVARS_IV]], -1
240; CHECK-NEXT:    [[TMP0:%.*]] = trunc i32 [[INDVARS_IV_NEXT]] to i8
241; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[TMP0]], -14
242; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
243; CHECK:       for.end:
244; CHECK-NEXT:    ret i32 0
245;
246entry:
247  br label %for.body
248
249for.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
258
259for.end:
260  ret i32 0
261}
262
263
264define i32 @test5(i32* %a, i32 %b) {
265; CHECK-LABEL: @test5(
266; CHECK-NEXT:  entry:
267; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[B:%.*]] to i64
268; CHECK-NEXT:    br label [[FOR_COND:%.*]]
269; CHECK:       for.cond:
270; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
271; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
272; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP0]]
273; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
274; CHECK:       for.body:
275; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
276; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
277; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]]
278; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw i64 [[INDVARS_IV]], 1
279; CHECK-NEXT:    br label [[FOR_COND]]
280; CHECK:       for.end:
281; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ]
282; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
283;
284entry:
285  br label %for.cond
286
287for.cond:
288  %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
289  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
290  %cmp = icmp ule i32 %i.0, %b
291  br i1 %cmp, label %for.body, label %for.end
292
293for.body:
294  %idxprom = zext i32 %i.0 to i64
295  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
296  %0 = load i32, i32* %arrayidx, align 4
297  %add = add nsw i32 %sum.0, %0
298  %inc = add nsw i32 %i.0, 1
299  br label %for.cond
300
301for.end:
302  ret i32 %sum.0
303}
304
305define i32 @test6(i32* %a, i32 %b) {
306; CHECK-LABEL: @test6(
307; CHECK-NEXT:  entry:
308; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B:%.*]], i32 -1)
309; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[SMAX]], 1
310; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP0]] to i64
311; CHECK-NEXT:    br label [[FOR_COND:%.*]]
312; CHECK:       for.cond:
313; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
314; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
315; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
316; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
317; CHECK:       for.body:
318; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
319; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
320; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]]
321; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
322; CHECK-NEXT:    br label [[FOR_COND]]
323; CHECK:       for.end:
324; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ]
325; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
326;
327entry:
328  br label %for.cond
329
330for.cond:
331  %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
332  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
333  %cmp = icmp sle i32 %i.0, %b
334  br i1 %cmp, label %for.body, label %for.end
335
336for.body:
337  %idxprom = zext i32 %i.0 to i64
338  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
339  %0 = load i32, i32* %arrayidx, align 4
340  %add = add nsw i32 %sum.0, %0
341  %inc = add nsw i32 %i.0, 1
342  br label %for.cond
343
344for.end:
345  ret i32 %sum.0
346}
347
348define i32 @test7(i32* %a, i32 %b) {
349; CHECK-LABEL: @test7(
350; CHECK-NEXT:  entry:
351; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[B:%.*]] to i64
352; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 -1)
353; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[SMAX]], 2
354; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP1]] to i64
355; CHECK-NEXT:    br label [[FOR_COND:%.*]]
356; CHECK:       for.cond:
357; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
358; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
359; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP0]]
360; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
361; CHECK:       for.body:
362; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
363; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
364; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]]
365; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
366; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
367; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND]], label [[FOR_END]]
368; CHECK:       for.end:
369; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
370; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
371;
372entry:
373  br label %for.cond
374
375for.cond:
376  %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
377  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
378  %cmp = icmp ule i32 %i.0, %b
379  br i1 %cmp, label %for.body, label %for.end
380
381for.body:
382  %idxprom = sext i32 %i.0 to i64
383  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
384  %0 = load i32, i32* %arrayidx, align 4
385  %add = add nsw i32 %sum.0, %0
386  %inc = add nsw i32 %i.0, 1
387  %cmp2 = icmp sle i32 %i.0, %b
388  br i1 %cmp2, label %for.cond, label %for.end
389
390for.end:
391  ret i32 %sum.0
392}
393
394define i32 @test8(i32* %a, i32 %b, i32 %init) {
395;     Note: %indvars.iv is the sign extension of %i.0
396; CHECK-LABEL: @test8(
397; CHECK-NEXT:  entry:
398; CHECK-NEXT:    [[E:%.*]] = icmp sgt i32 [[INIT:%.*]], 0
399; CHECK-NEXT:    br i1 [[E]], label [[FOR_COND_PREHEADER:%.*]], label [[LEAVE:%.*]]
400; CHECK:       for.cond.preheader:
401; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[INIT]] to i64
402; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[B:%.*]] to i64
403; CHECK-NEXT:    br label [[FOR_COND:%.*]]
404; CHECK:       for.cond:
405; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ]
406; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ]
407; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP1]]
408; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
409; CHECK:       for.body:
410; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
411; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
412; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]]
413; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
414; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i64 0, [[INDVARS_IV_NEXT]]
415; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[FOR_END]]
416; CHECK:       for.end:
417; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
418; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
419; CHECK:       leave:
420; CHECK-NEXT:    ret i32 0
421;
422entry:
423  %e = icmp sgt i32 %init, 0
424  br i1 %e, label %for.cond, label %leave
425
426for.cond:
427  %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
428  %i.0 = phi i32 [ %init, %entry ], [ %inc, %for.body ]
429  %cmp = icmp ule i32 %i.0, %b
430  br i1 %cmp, label %for.body, label %for.end
431
432for.body:
433  %idxprom = sext i32 %i.0 to i64
434  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
435  %0 = load i32, i32* %arrayidx, align 4
436  %add = add nsw i32 %sum.0, %0
437  %inc = add nsw i32 %i.0, 1
438  %cmp2 = icmp slt i32 0, %inc
439  br i1 %cmp2, label %for.cond, label %for.end
440
441for.end:
442  ret i32 %sum.0
443
444leave:
445  ret i32 0
446}
447
448define i32 @test9(i32* %a, i32 %b, i32 %init) {
449;     Note: %indvars.iv is the zero extension of %i.0
450; CHECK-LABEL: @test9(
451; CHECK-NEXT:  entry:
452; CHECK-NEXT:    [[E:%.*]] = icmp sgt i32 [[INIT:%.*]], 0
453; CHECK-NEXT:    br i1 [[E]], label [[FOR_COND_PREHEADER:%.*]], label [[LEAVE:%.*]]
454; CHECK:       for.cond.preheader:
455; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[INIT]] to i64
456; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[INIT]], i32 [[B:%.*]])
457; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
458; CHECK-NEXT:    br label [[FOR_COND:%.*]]
459; CHECK:       for.cond:
460; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ]
461; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ]
462; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
463; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
464; CHECK:       for.body:
465; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
466; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
467; CHECK-NEXT:    [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]]
468; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
469; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
470; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 0, [[TMP2]]
471; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_COND]], label [[FOR_END]]
472; CHECK:       for.end:
473; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
474; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
475; CHECK:       leave:
476; CHECK-NEXT:    ret i32 0
477;
478entry:
479  %e = icmp sgt i32 %init, 0
480  br i1 %e, label %for.cond, label %leave
481
482for.cond:
483  %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
484  %i.0 = phi i32 [ %init, %entry ], [ %inc, %for.body ]
485  %cmp = icmp slt i32 %i.0, %b
486  br i1 %cmp, label %for.body, label %for.end
487
488for.body:
489  %idxprom = zext i32 %i.0 to i64
490  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
491  %0 = load i32, i32* %arrayidx, align 4
492  %add = add nsw i32 %sum.0, %0
493  %inc = add nsw i32 %i.0, 1
494  %cmp2 = icmp slt i32 0, %inc
495  br i1 %cmp2, label %for.cond, label %for.end
496
497for.end:
498  ret i32 %sum.0
499
500leave:
501  ret i32 0
502}
503
504declare void @consume.i64(i64)
505declare void @consume.i1(i1)
506
507define i32 @test10(i32 %v) {
508; CHECK-LABEL: @test10(
509; CHECK-NEXT:  entry:
510; CHECK-NEXT:    [[SEXT:%.*]] = sext i32 [[V:%.*]] to i64
511; CHECK-NEXT:    br label [[LOOP:%.*]]
512; CHECK:       loop:
513; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
514; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
515; CHECK-NEXT:    [[TMP0:%.*]] = mul nsw i64 [[INDVARS_IV]], -1
516; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], [[SEXT]]
517; CHECK-NEXT:    call void @consume.i1(i1 [[TMP1]])
518; CHECK-NEXT:    call void @consume.i64(i64 [[TMP0]])
519; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 11
520; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE:%.*]]
521; CHECK:       leave:
522; CHECK-NEXT:    ret i32 22
523;
524  entry:
525  br label %loop
526
527  loop:
528
529  %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
530  %i.inc = add i32 %i, 1
531  %iv = mul i32 %i, -1
532  %cmp = icmp eq i32 %iv, %v
533  call void @consume.i1(i1 %cmp)
534  %be.cond = icmp slt i32 %i.inc, 11
535  %ext = sext i32 %iv to i64
536  call void @consume.i64(i64 %ext)
537  br i1 %be.cond, label %loop, label %leave
538
539  leave:
540  ret i32 22
541}
542
543; TODO: We don't really need trunc/zext here because when iv.next overflows,
544; its value is not used.
545define i32 @test11(i32 %start, i32* %p, i32* %q) {
546; CHECK-LABEL: @test11(
547; CHECK-NEXT:  entry:
548; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
549; CHECK-NEXT:    br label [[LOOP:%.*]]
550; CHECK:       loop:
551; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
552; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
553; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
554; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
555; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
556; CHECK:       backedge:
557; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
558; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
559; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
560; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
561; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
562; CHECK:       exit:
563; CHECK-NEXT:    ret i32 0
564; CHECK:       failure:
565; CHECK-NEXT:    unreachable
566;
567entry:
568  br label %loop
569
570loop:
571  %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
572  %iv.next = add i32 %iv, -1
573  %cond = icmp eq i32 %iv, 0
574  br i1 %cond, label %exit, label %backedge
575
576backedge:
577  %index = zext i32 %iv.next to i64
578  %store.addr = getelementptr i32, i32* %p, i64 %index
579  store i32 1, i32* %store.addr
580  %load.addr = getelementptr i32, i32* %q, i64 %index
581  %stop = load i32, i32* %q
582  %loop.cond = icmp eq i32 %stop, 0
583  br i1 %loop.cond, label %loop, label %failure
584
585exit:
586  ret i32 0
587
588failure:
589  unreachable
590}
591
592define i32 @test12(i32 %start, i32* %p, i32* %q) {
593; CHECK-LABEL: @test12(
594; CHECK-NEXT:  entry:
595; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
596; CHECK-NEXT:    br label [[LOOP:%.*]]
597; CHECK:       loop:
598; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
599; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
600; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
601; CHECK:       backedge:
602; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
603; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
604; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
605; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
606; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
607; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
608; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
609; CHECK:       exit:
610; CHECK-NEXT:    ret i32 0
611; CHECK:       failure:
612; CHECK-NEXT:    unreachable
613;
614entry:
615  br label %loop
616
617loop:
618  %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
619  %cond = icmp eq i32 %iv, 0
620  br i1 %cond, label %exit, label %backedge
621
622backedge:
623  %iv.next = add i32 %iv, -1
624  %index = zext i32 %iv.next to i64
625  %store.addr = getelementptr i32, i32* %p, i64 %index
626  store i32 1, i32* %store.addr
627  %load.addr = getelementptr i32, i32* %q, i64 %index
628  %stop = load i32, i32* %q
629  %loop.cond = icmp eq i32 %stop, 0
630  br i1 %loop.cond, label %loop, label %failure
631
632exit:
633  ret i32 0
634
635failure:
636  unreachable
637}
638
639define i32 @test13(i32 %start, i32* %p, i32* %q) {
640; CHECK-LABEL: @test13(
641; CHECK-NEXT:  entry:
642; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
643; CHECK-NEXT:    br label [[LOOP:%.*]]
644; CHECK:       loop:
645; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
646; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
647; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
648; CHECK:       backedge:
649; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
650; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
651; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
652; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
653; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
654; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
655; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
656; CHECK:       exit:
657; CHECK-NEXT:    ret i32 0
658; CHECK:       failure:
659; CHECK-NEXT:    unreachable
660;
661entry:
662  br label %loop
663
664loop:
665  %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
666  %cond = icmp eq i32 %iv, 0
667  br i1 %cond, label %exit, label %backedge
668
669backedge:
670  %foo = add i32 %iv, -1
671  %index = zext i32 %foo to i64
672  %store.addr = getelementptr i32, i32* %p, i64 %index
673  store i32 1, i32* %store.addr
674  %load.addr = getelementptr i32, i32* %q, i64 %index
675  %stop = load i32, i32* %q
676  %loop.cond = icmp eq i32 %stop, 0
677  %iv.next.1 = add i32 %iv, -1
678  br i1 %loop.cond, label %loop, label %failure
679
680exit:
681  ret i32 0
682
683failure:
684  unreachable
685}
686
687define i32 @test14(i32 %start, i32* %p, i32* %q) {
688; CHECK-LABEL: @test14(
689; CHECK-NEXT:  entry:
690; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
691; CHECK-NEXT:    br label [[LOOP:%.*]]
692; CHECK:       loop:
693; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
694; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
695; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
696; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
697; CHECK:       backedge:
698; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
699; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
700; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
701; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
702; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
703; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
704; CHECK:       exit:
705; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
706; CHECK-NEXT:    ret i32 [[TMP2]]
707; CHECK:       failure:
708; CHECK-NEXT:    unreachable
709;
710entry:
711  br label %loop
712
713loop:
714  %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
715  %cond = icmp eq i32 %iv, 0
716  %foo = add i32 %iv, -1
717  br i1 %cond, label %exit, label %backedge
718
719backedge:
720  %index = zext i32 %foo to i64
721  %store.addr = getelementptr i32, i32* %p, i64 %index
722  store i32 1, i32* %store.addr
723  %load.addr = getelementptr i32, i32* %q, i64 %index
724  %stop = load i32, i32* %q
725  %loop.cond = icmp eq i32 %stop, 0
726  %iv.next.1 = add i32 %iv, -1
727  br i1 %loop.cond, label %loop, label %failure
728
729exit:
730  ret i32 %foo
731
732failure:
733  unreachable
734}
735
736declare void @test14a-callee(i1 %cond)
737
738; Same as @test14 but with unwind exit.
739; Trunc instructions must be added below the landing pad.
740define i32 @test14a(i32 %start, i32* %p, i32* %q, i1 %c) personality i1 1 {
741; CHECK-LABEL: @test14a(
742; CHECK-NEXT:  entry:
743; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
744; CHECK-NEXT:    br label [[LOOP:%.*]]
745; CHECK:       loop:
746; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
747; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
748; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
749; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
750; CHECK:       backedge:
751; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
752; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
753; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
754; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
755; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
756; CHECK-NEXT:    invoke void @test14a-callee(i1 [[LOOP_COND]])
757; CHECK-NEXT:    to label [[LOOP]] unwind label [[EXCEPTION:%.*]]
758; CHECK:       exit:
759; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
760; CHECK-NEXT:    ret i32 [[TMP2]]
761; CHECK:       exception:
762; CHECK-NEXT:    [[FOO_LCSSA1_WIDE:%.*]] = phi i64 [ [[TMP1]], [[BACKEDGE]] ]
763; CHECK-NEXT:    [[TMP3:%.*]] = landingpad i1
764; CHECK-NEXT:    cleanup
765; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 [[FOO_LCSSA1_WIDE]] to i32
766; CHECK-NEXT:    ret i32 [[TMP4]]
767;
768entry:
769  br label %loop
770
771loop:
772  %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
773  %cond = icmp eq i32 %iv, 0
774  %foo = add i32 %iv, -1
775  br i1 %cond, label %exit, label %backedge
776
777backedge:
778  %index = zext i32 %foo to i64
779  %store.addr = getelementptr i32, i32* %p, i64 %index
780  store i32 1, i32* %store.addr
781  %load.addr = getelementptr i32, i32* %q, i64 %index
782  %stop = load i32, i32* %q
783  %loop.cond = icmp eq i32 %stop, 0
784  %iv.next.1 = add i32 %iv, -1
785  invoke void @test14a-callee(i1 %loop.cond) to label %loop unwind label %exception
786
787exit:
788  ret i32 %foo
789
790exception:
791  landingpad i1
792  cleanup
793  ret i32 %foo
794}
795
796declare void @use(i32 %arg)
797
798define i32 @test15(i32 %start, i32* %p, i32* %q) {
799; CHECK-LABEL: @test15(
800; CHECK-NEXT:  entry:
801; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
802; CHECK-NEXT:    br label [[LOOP:%.*]]
803; CHECK:       loop:
804; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
805; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
806; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
807; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
808; CHECK:       backedge:
809; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
810; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
811; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
812; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
813; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
814; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
815; CHECK:       exit:
816; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
817; CHECK-NEXT:    call void @use(i32 [[TMP2]])
818; CHECK-NEXT:    ret i32 [[TMP2]]
819; CHECK:       failure:
820; CHECK-NEXT:    [[FOO_LCSSA1_WIDE:%.*]] = phi i64 [ [[TMP1]], [[BACKEDGE]] ]
821; CHECK-NEXT:    [[TMP3:%.*]] = trunc i64 [[FOO_LCSSA1_WIDE]] to i32
822; CHECK-NEXT:    call void @use(i32 [[TMP3]])
823; CHECK-NEXT:    unreachable
824;
825entry:
826  br label %loop
827
828loop:
829  %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
830  %cond = icmp eq i32 %iv, 0
831  %foo = add i32 %iv, -1
832  br i1 %cond, label %exit, label %backedge
833
834backedge:
835  %index = zext i32 %foo to i64
836  %store.addr = getelementptr i32, i32* %p, i64 %index
837  store i32 1, i32* %store.addr
838  %load.addr = getelementptr i32, i32* %q, i64 %index
839  %stop = load i32, i32* %q
840  %loop.cond = icmp eq i32 %stop, 0
841  %iv.next.1 = add i32 %iv, -1
842  br i1 %loop.cond, label %loop, label %failure
843
844exit:
845  call void @use(i32 %foo)
846  ret i32 %foo
847
848failure:
849  call void @use(i32 %foo)
850  unreachable
851}
852
853define i32 @test16_unsigned_pos1(i32 %start, i32* %p, i32* %q, i32 %x) {
854; CHECK-LABEL: @test16_unsigned_pos1(
855; CHECK-NEXT:  entry:
856; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
857; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[TMP0]], -1
858; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[X:%.*]] to i64
859; CHECK-NEXT:    br label [[LOOP:%.*]]
860; CHECK:       loop:
861; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
862; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
863; CHECK-NEXT:    [[TMP3:%.*]] = add nsw i64 [[INDVARS_IV]], -1
864; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
865; CHECK:       guarded:
866; CHECK-NEXT:    [[ICMP_USER_WIDE5:%.*]] = icmp ult i64 [[TMP1]], [[TMP2]]
867; CHECK-NEXT:    br i1 [[ICMP_USER_WIDE5]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
868; CHECK:       backedge:
869; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP3]]
870; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
871; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
872; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
873; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
874; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
875; CHECK:       exit:
876; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 -1 to i32
877; CHECK-NEXT:    call void @use(i32 [[TMP4]])
878; CHECK-NEXT:    ret i32 [[TMP4]]
879; CHECK:       failure:
880; CHECK-NEXT:    [[FOO_LCSSA2_WIDE:%.*]] = phi i64 [ [[TMP3]], [[BACKEDGE]] ]
881; CHECK-NEXT:    [[TMP5:%.*]] = trunc i64 [[FOO_LCSSA2_WIDE]] to i32
882; CHECK-NEXT:    call void @use(i32 [[TMP5]])
883; CHECK-NEXT:    unreachable
884; CHECK:       side_exit:
885; CHECK-NEXT:    ret i32 0
886;
887entry:
888  br label %loop
889
890loop:
891  %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
892  %cond = icmp eq i32 %iv, 0
893  %foo = add i32 %iv, -1
894  br i1 %cond, label %exit, label %guarded
895
896guarded:
897  %icmp_user = icmp ult i32 %foo, %x
898  br i1 %icmp_user, label %backedge, label %side_exit
899
900backedge:
901  %index = zext i32 %foo to i64
902  %store.addr = getelementptr i32, i32* %p, i64 %index
903  store i32 1, i32* %store.addr
904  %load.addr = getelementptr i32, i32* %q, i64 %index
905  %stop = load i32, i32* %q
906  %loop.cond = icmp eq i32 %stop, 0
907  %iv.next.1 = add i32 %iv, -1
908  br i1 %loop.cond, label %loop, label %failure
909
910exit:
911  call void @use(i32 %foo)
912  ret i32 %foo
913
914failure:
915  call void @use(i32 %foo)
916  unreachable
917
918side_exit:
919  ret i32 0
920}
921
922; TODO: We can widen here despite the icmp user of %foo in guarded block.
923define i32 @test16_unsigned_pos2(i32 %start, i32* %p, i32* %q, i32 %x) {
924; CHECK-LABEL: @test16_unsigned_pos2(
925; CHECK-NEXT:  entry:
926; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
927; CHECK-NEXT:    br label [[LOOP:%.*]]
928; CHECK:       loop:
929; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
930; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
931; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[INDVARS_IV]] to i32
932; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[TMP1]], -1
933; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
934; CHECK:       guarded:
935; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp ne i32 [[FOO]], [[X:%.*]]
936; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
937; CHECK:       backedge:
938; CHECK-NEXT:    [[INDEX:%.*]] = zext i32 [[FOO]] to i64
939; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[INDEX]]
940; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
941; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 [[INDEX]]
942; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[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:    call void @use(i32 -1)
948; CHECK-NEXT:    ret i32 -1
949; CHECK:       failure:
950; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
951; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
952; CHECK-NEXT:    unreachable
953; CHECK:       side_exit:
954; CHECK-NEXT:    ret i32 0
955;
956entry:
957  br label %loop
958
959loop:
960  %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
961  %cond = icmp eq i32 %iv, 0
962  %foo = add i32 %iv, -1
963  br i1 %cond, label %exit, label %guarded
964
965guarded:
966  %icmp_user = icmp ne i32 %foo, %x
967  br i1 %icmp_user, label %backedge, label %side_exit
968
969backedge:
970  %index = zext i32 %foo to i64
971  %store.addr = getelementptr i32, i32* %p, i64 %index
972  store i32 1, i32* %store.addr
973  %load.addr = getelementptr i32, i32* %q, i64 %index
974  %stop = load i32, i32* %q
975  %loop.cond = icmp eq i32 %stop, 0
976  %iv.next.1 = add i32 %iv, -1
977  br i1 %loop.cond, label %loop, label %failure
978
979exit:
980  call void @use(i32 %foo)
981  ret i32 %foo
982
983failure:
984  call void @use(i32 %foo)
985  unreachable
986
987side_exit:
988  ret i32 0
989}
990
991; icmp slt user in guarded block prevents widening.
992define i32 @test16_unsigned_neg(i32 %start, i32* %p, i32* %q, i32 %x) {
993; CHECK-LABEL: @test16_unsigned_neg(
994; CHECK-NEXT:  entry:
995; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
996; CHECK-NEXT:    br label [[LOOP:%.*]]
997; CHECK:       loop:
998; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
999; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
1000; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[INDVARS_IV]] to i32
1001; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[TMP1]], -1
1002; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1003; CHECK:       guarded:
1004; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp slt i32 [[FOO]], [[X:%.*]]
1005; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1006; CHECK:       backedge:
1007; CHECK-NEXT:    [[INDEX:%.*]] = zext i32 [[FOO]] to i64
1008; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[INDEX]]
1009; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
1010; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 [[INDEX]]
1011; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q]], align 4
1012; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1013; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
1014; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1015; CHECK:       exit:
1016; CHECK-NEXT:    call void @use(i32 -1)
1017; CHECK-NEXT:    ret i32 -1
1018; CHECK:       failure:
1019; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1020; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1021; CHECK-NEXT:    unreachable
1022; CHECK:       side_exit:
1023; CHECK-NEXT:    ret i32 0
1024;
1025entry:
1026  br label %loop
1027
1028loop:
1029  %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1030  %cond = icmp eq i32 %iv, 0
1031  %foo = add i32 %iv, -1
1032  br i1 %cond, label %exit, label %guarded
1033
1034guarded:
1035  %icmp_user = icmp slt i32 %foo, %x
1036  br i1 %icmp_user, label %backedge, label %side_exit
1037
1038backedge:
1039  %index = zext i32 %foo to i64
1040  %store.addr = getelementptr i32, i32* %p, i64 %index
1041  store i32 1, i32* %store.addr
1042  %load.addr = getelementptr i32, i32* %q, i64 %index
1043  %stop = load i32, i32* %q
1044  %loop.cond = icmp eq i32 %stop, 0
1045  %iv.next.1 = add i32 %iv, -1
1046  br i1 %loop.cond, label %loop, label %failure
1047
1048exit:
1049  call void @use(i32 %foo)
1050  ret i32 %foo
1051
1052failure:
1053  call void @use(i32 %foo)
1054  unreachable
1055
1056side_exit:
1057  ret i32 0
1058}
1059
1060; TODO: We can widen here despite the icmp user of %foo in guarded block.
1061define i32 @test16_signed_pos1(i32 %start, i32* %p, i32* %q, i32 %x) {
1062; CHECK-LABEL: @test16_signed_pos1(
1063; CHECK-NEXT:  entry:
1064; CHECK-NEXT:    br label [[LOOP:%.*]]
1065; CHECK:       loop:
1066; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT_1:%.*]], [[BACKEDGE:%.*]] ]
1067; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[IV]], 0
1068; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[IV]], -1
1069; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1070; CHECK:       guarded:
1071; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp slt i32 [[FOO]], [[X:%.*]]
1072; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1073; CHECK:       backedge:
1074; CHECK-NEXT:    [[INDEX:%.*]] = sext i32 [[FOO]] to i64
1075; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[INDEX]]
1076; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
1077; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 [[INDEX]]
1078; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q]], align 4
1079; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1080; CHECK-NEXT:    [[IV_NEXT_1]] = add i32 [[IV]], -1
1081; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1082; CHECK:       exit:
1083; CHECK-NEXT:    call void @use(i32 -1)
1084; CHECK-NEXT:    ret i32 -1
1085; CHECK:       failure:
1086; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1087; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1088; CHECK-NEXT:    unreachable
1089; CHECK:       side_exit:
1090; CHECK-NEXT:    ret i32 0
1091;
1092entry:
1093  br label %loop
1094
1095loop:
1096  %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1097  %cond = icmp eq i32 %iv, 0
1098  %foo = add i32 %iv, -1
1099  br i1 %cond, label %exit, label %guarded
1100
1101guarded:
1102  %icmp_user = icmp slt i32 %foo, %x
1103  br i1 %icmp_user, label %backedge, label %side_exit
1104
1105backedge:
1106  %index = sext i32 %foo to i64
1107  %store.addr = getelementptr i32, i32* %p, i64 %index
1108  store i32 1, i32* %store.addr
1109  %load.addr = getelementptr i32, i32* %q, i64 %index
1110  %stop = load i32, i32* %q
1111  %loop.cond = icmp eq i32 %stop, 0
1112  %iv.next.1 = add i32 %iv, -1
1113  br i1 %loop.cond, label %loop, label %failure
1114
1115exit:
1116  call void @use(i32 %foo)
1117  ret i32 %foo
1118
1119failure:
1120  call void @use(i32 %foo)
1121  unreachable
1122
1123side_exit:
1124  ret i32 0
1125}
1126
1127; TODO: We can widen here despite the icmp user of %foo in guarded block.
1128define i32 @test16_signed_pos2(i32 %start, i32* %p, i32* %q, i32 %x) {
1129; CHECK-LABEL: @test16_signed_pos2(
1130; CHECK-NEXT:  entry:
1131; CHECK-NEXT:    br label [[LOOP:%.*]]
1132; CHECK:       loop:
1133; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT_1:%.*]], [[BACKEDGE:%.*]] ]
1134; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[IV]], 0
1135; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[IV]], -1
1136; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1137; CHECK:       guarded:
1138; CHECK-NEXT:    [[ICMP_USER:%.*]] = icmp ne i32 [[FOO]], [[X:%.*]]
1139; CHECK-NEXT:    br i1 [[ICMP_USER]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1140; CHECK:       backedge:
1141; CHECK-NEXT:    [[INDEX:%.*]] = sext i32 [[FOO]] to i64
1142; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[INDEX]]
1143; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
1144; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 [[INDEX]]
1145; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q]], align 4
1146; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1147; CHECK-NEXT:    [[IV_NEXT_1]] = add i32 [[IV]], -1
1148; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1149; CHECK:       exit:
1150; CHECK-NEXT:    call void @use(i32 -1)
1151; CHECK-NEXT:    ret i32 -1
1152; CHECK:       failure:
1153; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1154; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1155; CHECK-NEXT:    unreachable
1156; CHECK:       side_exit:
1157; CHECK-NEXT:    ret i32 0
1158;
1159entry:
1160  br label %loop
1161
1162loop:
1163  %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1164  %cond = icmp eq i32 %iv, 0
1165  %foo = add i32 %iv, -1
1166  br i1 %cond, label %exit, label %guarded
1167
1168guarded:
1169  %icmp_user = icmp ne i32 %foo, %x
1170  br i1 %icmp_user, label %backedge, label %side_exit
1171
1172backedge:
1173  %index = sext i32 %foo to i64
1174  %store.addr = getelementptr i32, i32* %p, i64 %index
1175  store i32 1, i32* %store.addr
1176  %load.addr = getelementptr i32, i32* %q, i64 %index
1177  %stop = load i32, i32* %q
1178  %loop.cond = icmp eq i32 %stop, 0
1179  %iv.next.1 = add i32 %iv, -1
1180  br i1 %loop.cond, label %loop, label %failure
1181
1182exit:
1183  call void @use(i32 %foo)
1184  ret i32 %foo
1185
1186failure:
1187  call void @use(i32 %foo)
1188  unreachable
1189
1190side_exit:
1191  ret i32 0
1192}
1193
1194; icmp ult user in guarded block prevents widening.
1195define i32 @test16_signed_neg(i32 %start, i32* %p, i32* %q, i32 %x) {
1196; CHECK-LABEL: @test16_signed_neg(
1197; CHECK-NEXT:  entry:
1198; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[START:%.*]], -1
1199; CHECK-NEXT:    br label [[LOOP:%.*]]
1200; CHECK:       loop:
1201; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START]], [[ENTRY:%.*]] ], [ [[IV_NEXT_1:%.*]], [[BACKEDGE:%.*]] ]
1202; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[IV]], 0
1203; CHECK-NEXT:    [[FOO:%.*]] = add i32 [[IV]], -1
1204; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[GUARDED:%.*]]
1205; CHECK:       guarded:
1206; CHECK-NEXT:    [[ICMP_USER3:%.*]] = icmp ult i32 [[TMP0]], [[X:%.*]]
1207; CHECK-NEXT:    br i1 [[ICMP_USER3]], label [[BACKEDGE]], label [[SIDE_EXIT:%.*]]
1208; CHECK:       backedge:
1209; CHECK-NEXT:    [[INDEX:%.*]] = sext i32 [[FOO]] to i64
1210; CHECK-NEXT:    [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[INDEX]]
1211; CHECK-NEXT:    store i32 1, i32* [[STORE_ADDR]], align 4
1212; CHECK-NEXT:    [[LOAD_ADDR:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 [[INDEX]]
1213; CHECK-NEXT:    [[STOP:%.*]] = load i32, i32* [[Q]], align 4
1214; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
1215; CHECK-NEXT:    [[IV_NEXT_1]] = add i32 [[IV]], -1
1216; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
1217; CHECK:       exit:
1218; CHECK-NEXT:    call void @use(i32 -1)
1219; CHECK-NEXT:    ret i32 -1
1220; CHECK:       failure:
1221; CHECK-NEXT:    [[FOO_LCSSA2:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
1222; CHECK-NEXT:    call void @use(i32 [[FOO_LCSSA2]])
1223; CHECK-NEXT:    unreachable
1224; CHECK:       side_exit:
1225; CHECK-NEXT:    ret i32 0
1226;
1227entry:
1228  br label %loop
1229
1230loop:
1231  %iv = phi i32 [%start, %entry], [%iv.next.1, %backedge]
1232  %cond = icmp eq i32 %iv, 0
1233  %foo = add i32 %iv, -1
1234  br i1 %cond, label %exit, label %guarded
1235
1236guarded:
1237  %icmp_user = icmp ult i32 %foo, %x
1238  br i1 %icmp_user, label %backedge, label %side_exit
1239
1240backedge:
1241  %index = sext i32 %foo to i64
1242  %store.addr = getelementptr i32, i32* %p, i64 %index
1243  store i32 1, i32* %store.addr
1244  %load.addr = getelementptr i32, i32* %q, i64 %index
1245  %stop = load i32, i32* %q
1246  %loop.cond = icmp eq i32 %stop, 0
1247  %iv.next.1 = add i32 %iv, -1
1248  br i1 %loop.cond, label %loop, label %failure
1249
1250exit:
1251  call void @use(i32 %foo)
1252  ret i32 %foo
1253
1254failure:
1255  call void @use(i32 %foo)
1256  unreachable
1257
1258side_exit:
1259  ret i32 0
1260}
1261
1262define i32 @test17(i32* %p, i32 %len) {
1263; CHECK-LABEL: @test17(
1264; CHECK-NEXT:  entry:
1265; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[LEN:%.*]] to i64
1266; CHECK-NEXT:    br label [[LOOP:%.*]]
1267; CHECK:       loop:
1268; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
1269; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
1270; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
1271; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
1272; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
1273; CHECK:       backedge:
1274; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 [[TMP1]]
1275; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, i32* [[ADDR]] unordered, align 4
1276; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], 0
1277; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
1278; CHECK:       exit:
1279; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 -1 to i32
1280; CHECK-NEXT:    ret i32 [[TMP2]]
1281; CHECK:       failure:
1282; CHECK-NEXT:    unreachable
1283;
1284entry:
1285  br label %loop
1286
1287loop:
1288  %iv = phi i32 [ %iv.next, %backedge ], [ %len, %entry ]
1289  %iv.next = add i32 %iv, -1
1290  %cond_1 = icmp eq i32 %iv, 0
1291  br i1 %cond_1, label %exit, label %backedge
1292
1293backedge:
1294  %iv.next.wide = zext i32 %iv.next to i64
1295  %addr = getelementptr inbounds i32, i32* %p, i64 %iv.next.wide
1296  %loaded = load atomic i32, i32* %addr unordered, align 4
1297  %cond_2 = icmp eq i32 %loaded, 0
1298  br i1 %cond_2, label %failure, label %loop
1299
1300exit:
1301  ret i32 %iv.next
1302
1303failure:
1304  unreachable
1305}
1306
1307declare void @foo(i64 %v)
1308declare void @bar(i32 %v)
1309
1310define void @test18() {
1311; CHECK-LABEL: @test18(
1312; CHECK-NEXT:  entry:
1313; CHECK-NEXT:    br label [[LOOP:%.*]]
1314; CHECK:       loop:
1315; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1316; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1317; CHECK-NEXT:    [[INDVARS2:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
1318; CHECK-NEXT:    call void @bar(i32 [[INDVARS2]])
1319; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
1320; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
1321; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1322; CHECK:       exit:
1323; CHECK-NEXT:    ret void
1324;
1325entry:
1326  br label %loop
1327
1328loop:                                             ; preds = %loop, %entry
1329  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1330  %val1 = phi i32 [ %val1.inc, %loop ], [ 0, %entry ]
1331  %val1.inc = add i32 %val1, 1
1332  %iv.next = add i32 %iv, 1
1333  call void @bar(i32 %val1.inc)
1334  %iv.wide = zext i32 %iv to i64
1335  call void @foo(i64 %iv.wide)
1336  %loop.cond = icmp eq i32 %iv, 1000
1337  br i1 %loop.cond, label %exit, label %loop
1338
1339exit:                                             ; preds = %loop
1340  ret void
1341}
1342
1343define void @test19() {
1344; CHECK-LABEL: @test19(
1345; CHECK-NEXT:  entry:
1346; CHECK-NEXT:    br label [[LOOP:%.*]]
1347; CHECK:       loop:
1348; CHECK-NEXT:    [[VAL1:%.*]] = phi i64 [ [[VAL1_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1349; CHECK-NEXT:    [[VAL1_INC]] = add nuw nsw i64 [[VAL1]], 1
1350; CHECK-NEXT:    call void @foo(i64 [[VAL1_INC]])
1351; CHECK-NEXT:    call void @foo(i64 [[VAL1]])
1352; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[VAL1]], 1000
1353; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1354; CHECK:       exit:
1355; CHECK-NEXT:    ret void
1356;
1357entry:
1358  br label %loop
1359
1360loop:                                             ; preds = %loop, %entry
1361  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1362  %val1 = phi i64 [ %val1.inc, %loop ], [ 0, %entry ]
1363  %val1.inc = add i64 %val1, 1
1364  %iv.next = add i32 %iv, 1
1365  call void @foo(i64 %val1.inc)
1366  %iv.wide = zext i32 %iv to i64
1367  call void @foo(i64 %iv.wide)
1368  %loop.cond = icmp eq i32 %iv, 1000
1369  br i1 %loop.cond, label %exit, label %loop
1370
1371exit:                                             ; preds = %loop
1372  ret void
1373}
1374
1375define void @test20() {
1376; CHECK-LABEL: @test20(
1377; CHECK-NEXT:  entry:
1378; CHECK-NEXT:    br label [[LOOP:%.*]]
1379; CHECK:       loop:
1380; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1381; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1382; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
1383; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
1384; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
1385; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1386; CHECK:       exit:
1387; CHECK-NEXT:    ret void
1388;
1389entry:
1390  br label %loop
1391
1392loop:                                             ; preds = %loop, %entry
1393  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1394  %val1 = phi i32 [ %val1.inc, %loop ], [ 0, %entry ]
1395  %val1.inc = add i32 %val1, 1
1396  %iv.next = add i32 %iv, 1
1397  %val1.wide = zext i32 %val1 to i64
1398  call void @foo(i64 %val1.wide)
1399  %iv.wide = zext i32 %iv to i64
1400  call void @foo(i64 %iv.wide)
1401  %loop.cond = icmp eq i32 %iv, 1000
1402  br i1 %loop.cond, label %exit, label %loop
1403
1404exit:                                             ; preds = %loop
1405  ret void
1406}
1407
1408define void @test21(i32* %ptr) {
1409; CHECK-LABEL: @test21(
1410; CHECK-NEXT:  entry:
1411; CHECK-NEXT:    store i32 0, i32* [[PTR:%.*]], align 4
1412; CHECK-NEXT:    br label [[LOOP:%.*]]
1413; CHECK:       loop:
1414; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1415; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1416; CHECK-NEXT:    [[INDVARS:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
1417; CHECK-NEXT:    store i32 [[INDVARS]], i32* [[PTR]], align 4
1418; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
1419; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
1420; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1421; CHECK:       exit:
1422; CHECK-NEXT:    ret void
1423;
1424entry:
1425  store i32 0, i32* %ptr, align 4
1426  br label %loop
1427
1428loop:                                             ; preds = %loop, %entry
1429  %val = phi i32 [ %val.inc, %loop ], [ 0, %entry ]
1430  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1431  %val.inc = add i32 %val, 1
1432  store i32 %val.inc, i32* %ptr, align 4
1433  %iv.wide = zext i32 %iv to i64
1434  call void @foo(i64 %iv.wide)
1435  %iv.next = add i32 %iv, 1
1436  %loop.cond = icmp eq i32 %iv, 1000
1437  br i1 %loop.cond, label %exit, label %loop
1438
1439exit:                                             ; preds = %loop
1440  ret void
1441}
1442
1443define void @test22(i16* %ptr) {
1444; CHECK-LABEL: @test22(
1445; CHECK-NEXT:  entry:
1446; CHECK-NEXT:    store i16 0, i16* [[PTR:%.*]], align 4
1447; CHECK-NEXT:    br label [[LOOP:%.*]]
1448; CHECK:       loop:
1449; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
1450; CHECK-NEXT:    [[INDVARS:%.*]] = trunc i32 [[IV]] to i16
1451; CHECK-NEXT:    [[VAL_INC:%.*]] = add i16 [[INDVARS]], 1
1452; CHECK-NEXT:    store i16 [[VAL_INC]], i16* [[PTR]], align 4
1453; CHECK-NEXT:    [[IV_WIDE:%.*]] = zext i32 [[IV]] to i64
1454; CHECK-NEXT:    call void @foo(i64 [[IV_WIDE]])
1455; CHECK-NEXT:    [[IV_NEXT]] = zext i16 [[VAL_INC]] to i32
1456; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[IV]], 1000
1457; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
1458; CHECK:       exit:
1459; CHECK-NEXT:    ret void
1460;
1461entry:
1462  store i16 0, i16* %ptr, align 4
1463  br label %loop
1464
1465loop:                                             ; preds = %loop, %entry
1466  %val = phi i16 [ %val.inc, %loop ], [ 0, %entry ]
1467  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
1468  %val.inc = add i16 %val, 1
1469  store i16 %val.inc, i16* %ptr, align 4
1470  %iv.wide = zext i32 %iv to i64
1471  call void @foo(i64 %iv.wide)
1472  %iv.next = zext i16 %val.inc to i32
1473  %loop.cond = icmp eq i32 %iv, 1000
1474  br i1 %loop.cond, label %exit, label %loop
1475
1476exit:                                             ; preds = %loop
1477  ret void
1478}
1479