• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -indvars -S | FileCheck %s
3
4define void @test1() nounwind {
5; CHECK-LABEL: @test1(
6; CHECK-NEXT:  entry:
7; CHECK-NEXT:    br label [[BB:%.*]]
8; CHECK:       bb:
9; CHECK-NEXT:    [[IV_INT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[DOTINT:%.*]], [[BB]] ]
10; CHECK-NEXT:    [[INDVAR_CONV:%.*]] = sitofp i32 [[IV_INT]] to double
11; CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @foo(double [[INDVAR_CONV]]) [[ATTR0:#.*]]
12; CHECK-NEXT:    [[DOTINT]] = add nuw nsw i32 [[IV_INT]], 1
13; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[DOTINT]], 10000
14; CHECK-NEXT:    br i1 [[TMP1]], label [[BB]], label [[RETURN:%.*]]
15; CHECK:       return:
16; CHECK-NEXT:    ret void
17;
18entry:
19  br label %bb
20
21bb:		; preds = %bb, %entry
22  %iv = phi double [ 0.000000e+00, %entry ], [ %1, %bb ]
23  %0 = tail call i32 @foo(double %iv) nounwind
24  %1 = fadd double %iv, 1.000000e+00
25  %2 = fcmp olt double %1, 1.000000e+04
26  br i1 %2, label %bb, label %return
27
28return:		; preds = %bb
29  ret void
30}
31
32declare i32 @foo(double)
33
34define void @test2() nounwind {
35; CHECK-LABEL: @test2(
36; CHECK-NEXT:  entry:
37; CHECK-NEXT:    br label [[BB:%.*]]
38; CHECK:       bb:
39; CHECK-NEXT:    [[IV_INT:%.*]] = phi i32 [ -10, [[ENTRY:%.*]] ], [ [[DOTINT:%.*]], [[BB]] ]
40; CHECK-NEXT:    [[INDVAR_CONV:%.*]] = sitofp i32 [[IV_INT]] to double
41; CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @foo(double [[INDVAR_CONV]]) [[ATTR0]]
42; CHECK-NEXT:    [[DOTINT]] = add nsw i32 [[IV_INT]], 2
43; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[DOTINT]], -1
44; CHECK-NEXT:    br i1 [[TMP1]], label [[BB]], label [[RETURN:%.*]]
45; CHECK:       return:
46; CHECK-NEXT:    ret void
47;
48entry:
49  br label %bb
50
51bb:		; preds = %bb, %entry
52  %iv = phi double [ -10.000000e+00, %entry ], [ %1, %bb ]
53  %0 = tail call i32 @foo(double %iv) nounwind
54  %1 = fadd double %iv, 2.000000e+00
55  %2 = fcmp olt double %1, -1.000000e+00
56  br i1 %2, label %bb, label %return
57
58return:		; preds = %bb
59  ret void
60}
61
62
63define void @test3() nounwind {
64; CHECK-LABEL: @test3(
65; CHECK-NEXT:  entry:
66; CHECK-NEXT:    br label [[BB:%.*]]
67; CHECK:       bb:
68; CHECK-NEXT:    [[IV:%.*]] = phi double [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[BB]] ]
69; CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @foo(double [[IV]]) [[ATTR0]]
70; CHECK-NEXT:    [[TMP1]] = fadd double [[IV]], 1.000000e+00
71; CHECK-NEXT:    br i1 false, label [[BB]], label [[RETURN:%.*]]
72; CHECK:       return:
73; CHECK-NEXT:    ret void
74;
75entry:
76  br label %bb
77
78bb:		; preds = %bb, %entry
79  %iv = phi double [ 0.000000e+00, %entry ], [ %1, %bb ]
80  %0 = tail call i32 @foo(double %iv) nounwind
81  %1 = fadd double %iv, 1.000000e+00
82  %2 = fcmp olt double %1, -1.000000e+00
83  br i1 %2, label %bb, label %return
84
85return:
86  ret void
87}
88
89define void @test4() nounwind {
90; CHECK-LABEL: @test4(
91; CHECK-NEXT:  entry:
92; CHECK-NEXT:    br label [[BB:%.*]]
93; CHECK:       bb:
94; CHECK-NEXT:    [[IV_INT:%.*]] = phi i32 [ 40, [[ENTRY:%.*]] ], [ [[DOTINT:%.*]], [[BB]] ]
95; CHECK-NEXT:    [[INDVAR_CONV:%.*]] = sitofp i32 [[IV_INT]] to double
96; CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @foo(double [[INDVAR_CONV]]) [[ATTR0]]
97; CHECK-NEXT:    [[DOTINT]] = add nsw i32 [[IV_INT]], -1
98; CHECK-NEXT:    br i1 false, label [[BB]], label [[RETURN:%.*]]
99; CHECK:       return:
100; CHECK-NEXT:    ret void
101;
102entry:
103  br label %bb
104
105bb:		; preds = %bb, %entry
106  %iv = phi double [ 40.000000e+00, %entry ], [ %1, %bb ]
107  %0 = tail call i32 @foo(double %iv) nounwind
108  %1 = fadd double %iv, -1.000000e+00
109  %2 = fcmp olt double %1, 1.000000e+00
110  br i1 %2, label %bb, label %return
111
112return:
113  ret void
114}
115
116; PR6761
117define void @test5() nounwind {
118; <label>:0
119; CHECK-LABEL: @test5(
120; CHECK-NEXT:    br label [[TMP1:%.*]]
121; CHECK:       1:
122; CHECK-NEXT:    [[DOTINT:%.*]] = phi i32 [ 9, [[TMP0:%.*]] ], [ [[DOTINT1:%.*]], [[TMP1]] ]
123; CHECK-NEXT:    [[TMP2:%.*]] = tail call i32 @foo(double 0.000000e+00)
124; CHECK-NEXT:    [[DOTINT1]] = add nsw i32 [[DOTINT]], -1
125; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[DOTINT1]], 0
126; CHECK-NEXT:    br i1 [[TMP3]], label [[EXIT:%.*]], label [[TMP1]]
127; CHECK:       exit:
128; CHECK-NEXT:    ret void
129;
130  br label %1
131
132; <label>:1
133  %2 = phi double [ 9.000000e+00, %0 ], [ %4, %1 ]
134  %3 = tail call i32 @foo(double 0.0)
135  %4 = fadd double %2, -1.000000e+00
136  %5 = fcmp ult double %4, 0.000000e+00
137  br i1 %5, label %exit, label %1
138
139exit:
140  ret void
141}
142
143define double @test_max_be() {
144; CHECK-LABEL: @test_max_be(
145; CHECK-NEXT:  bb4:
146; CHECK-NEXT:    br label [[BB8:%.*]]
147; CHECK:       bb8:
148; CHECK-NEXT:    [[TMP10:%.*]] = phi double [ 0.000000e+00, [[BB4:%.*]] ], [ [[TMP12:%.*]], [[BB22:%.*]] ]
149; CHECK-NEXT:    [[TMP11_INT:%.*]] = phi i32 [ 0, [[BB4]] ], [ [[TMP13_INT:%.*]], [[BB22]] ]
150; CHECK-NEXT:    [[INDVAR_CONV:%.*]] = sitofp i32 [[TMP11_INT]] to double
151; CHECK-NEXT:    [[TMP12]] = fadd double [[TMP10]], [[INDVAR_CONV]]
152; CHECK-NEXT:    [[TMP13_INT]] = add nuw nsw i32 [[TMP11_INT]], 1
153; CHECK-NEXT:    [[TMP14:%.*]] = icmp ult i32 [[TMP13_INT]], 99999
154; CHECK-NEXT:    br i1 [[TMP14]], label [[BB22]], label [[BB6:%.*]]
155; CHECK:       bb22:
156; CHECK-NEXT:    br i1 true, label [[BB8]], label [[BB6]]
157; CHECK:       bb6:
158; CHECK-NEXT:    [[TMP12_LCSSA:%.*]] = phi double [ [[TMP12]], [[BB22]] ], [ [[TMP12]], [[BB8]] ]
159; CHECK-NEXT:    ret double [[TMP12_LCSSA]]
160;
161bb4:
162  br label %bb8
163
164bb8:
165  %tmp9 = phi i64 [ 1, %bb4 ], [ %tmp23, %bb22 ]
166  %tmp10 = phi double [ 0.000000e+00, %bb4 ], [ %tmp12, %bb22 ]
167  %tmp11 = phi double [ 0.000000e+00, %bb4 ], [ %tmp13, %bb22 ]
168  %tmp12 = fadd double %tmp10, %tmp11
169  %tmp13 = fadd double %tmp11, 1.000000e+00
170  %tmp14 = fcmp olt double %tmp13, 9.999900e+04
171  br i1 %tmp14, label %bb22, label %bb6
172
173bb22:
174  %tmp23 = add nuw nsw i64 %tmp9, 1
175  %tmp24 = icmp ult i64 %tmp9, 1048576
176  br i1 %tmp24, label %bb8, label %bb6
177
178bb6:
179  ret double %tmp12
180}
181
182define float @test_max_be2() {
183; CHECK-LABEL: @test_max_be2(
184; CHECK-NEXT:  bb4:
185; CHECK-NEXT:    br label [[BB8:%.*]]
186; CHECK:       bb8:
187; CHECK-NEXT:    [[TMP10:%.*]] = phi float [ 0.000000e+00, [[BB4:%.*]] ], [ [[TMP12:%.*]], [[BB22:%.*]] ]
188; CHECK-NEXT:    [[TMP11_INT:%.*]] = phi i32 [ 0, [[BB4]] ], [ [[TMP13_INT:%.*]], [[BB22]] ]
189; CHECK-NEXT:    [[INDVAR_CONV:%.*]] = sitofp i32 [[TMP11_INT]] to float
190; CHECK-NEXT:    [[TMP12]] = fadd float [[TMP10]], [[INDVAR_CONV]]
191; CHECK-NEXT:    [[TMP13_INT]] = add nuw nsw i32 [[TMP11_INT]], 1
192; CHECK-NEXT:    [[TMP14:%.*]] = icmp ult i32 [[TMP13_INT]], 99999
193; CHECK-NEXT:    br i1 [[TMP14]], label [[BB22]], label [[BB6:%.*]]
194; CHECK:       bb22:
195; CHECK-NEXT:    br i1 true, label [[BB8]], label [[BB6]]
196; CHECK:       bb6:
197; CHECK-NEXT:    [[TMP12_LCSSA:%.*]] = phi float [ [[TMP12]], [[BB22]] ], [ [[TMP12]], [[BB8]] ]
198; CHECK-NEXT:    ret float [[TMP12_LCSSA]]
199;
200bb4:
201  br label %bb8
202
203bb8:
204  %tmp9 = phi i64 [ 1, %bb4 ], [ %tmp23, %bb22 ]
205  %tmp10 = phi float [ 0.000000e+00, %bb4 ], [ %tmp12, %bb22 ]
206  %tmp11 = phi float [ 0.000000e+00, %bb4 ], [ %tmp13, %bb22 ]
207  %tmp12 = fadd float %tmp10, %tmp11
208  %tmp13 = fadd float %tmp11, 1.000000e+00
209  %tmp14 = fcmp olt float %tmp13, 9.999900e+04
210  br i1 %tmp14, label %bb22, label %bb6
211
212bb22:
213  %tmp23 = add nuw nsw i64 %tmp9, 1
214  %tmp24 = icmp ult i64 %tmp9, 1048576
215  br i1 %tmp24, label %bb8, label %bb6
216
217bb6:
218  ret float %tmp12
219}
220
221; Bounds check
222define float @test_max_be3() {
223; CHECK-LABEL: @test_max_be3(
224; CHECK-NEXT:  bb4:
225; CHECK-NEXT:    br label [[BB8:%.*]]
226; CHECK:       bb8:
227; CHECK-NEXT:    [[TMP10:%.*]] = phi float [ 0.000000e+00, [[BB4:%.*]] ], [ [[TMP12:%.*]], [[BB22:%.*]] ]
228; CHECK-NEXT:    [[TMP11_INT:%.*]] = phi i32 [ 0, [[BB4]] ], [ [[TMP13_INT:%.*]], [[BB22]] ]
229; CHECK-NEXT:    [[INDVAR_CONV:%.*]] = sitofp i32 [[TMP11_INT]] to float
230; CHECK-NEXT:    [[TMP12]] = fadd float [[TMP10]], [[INDVAR_CONV]]
231; CHECK-NEXT:    [[TMP13_INT]] = add nuw nsw i32 [[TMP11_INT]], 1
232; CHECK-NEXT:    [[TMP14:%.*]] = icmp ult i32 [[TMP13_INT]], 99999
233; CHECK-NEXT:    br i1 [[TMP14]], label [[BB22]], label [[BB6:%.*]]
234; CHECK:       bb22:
235; CHECK-NEXT:    br i1 true, label [[BB8]], label [[BB6]]
236; CHECK:       bb6:
237; CHECK-NEXT:    [[TMP12_LCSSA:%.*]] = phi float [ [[TMP12]], [[BB22]] ], [ [[TMP12]], [[BB8]] ]
238; CHECK-NEXT:    ret float [[TMP12_LCSSA]]
239;
240bb4:
241  br label %bb8
242
243bb8:
244  %tmp9 = phi i64 [ 1, %bb4 ], [ %tmp23, %bb22 ]
245  %tmp10 = phi float [ 0.000000e+00, %bb4 ], [ %tmp12, %bb22 ]
246  %tmp11 = phi float [ 0.000000e+00, %bb4 ], [ %tmp13, %bb22 ]
247  %tmp12 = fadd float %tmp10, %tmp11
248  %tmp13 = fadd float %tmp11, 1.000000e+00
249  %tmp14 = fcmp olt float %tmp13, 9.999900e+04
250  br i1 %tmp14, label %bb22, label %bb6
251
252bb22:
253  %tmp23 = add nuw nsw i64 %tmp9, 1
254  ;; 2^23 = 16777215
255  %tmp24 = icmp ult i64 %tmp9, 16777215
256  br i1 %tmp24, label %bb8, label %bb6
257
258bb6:
259  ret float %tmp12
260}
261
262
263; Show that given a computeable exit count, we can remove an
264; fcmp of a casted integer IV. (TODO)
265define void @fcmp1() nounwind {
266; CHECK-LABEL: @fcmp1(
267; CHECK-NEXT:  entry:
268; CHECK-NEXT:    br label [[BB:%.*]]
269; CHECK:       bb:
270; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
271; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IV]], 20000
272; CHECK-NEXT:    br i1 [[CMP1]], label [[BACKEDGE]], label [[RETURN:%.*]]
273; CHECK:       backedge:
274; CHECK-NEXT:    [[IV_FP:%.*]] = sitofp i64 [[IV]] to double
275; CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @foo(double [[IV_FP]]) [[ATTR0]]
276; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
277; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt double [[IV_FP]], 1.000000e+04
278; CHECK-NEXT:    br i1 [[CMP2]], label [[BB]], label [[RETURN]]
279; CHECK:       return:
280; CHECK-NEXT:    ret void
281;
282entry:
283  br label %bb
284
285bb:		; preds = %bb, %entry
286  %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
287  %cmp1 = icmp slt i64 %iv, 20000
288  br i1 %cmp1, label %backedge, label %return
289
290backedge:
291  %iv.fp = sitofp i64 %iv to double
292  tail call i32 @foo(double %iv.fp) nounwind
293  %iv.next = add nsw nuw i64 %iv, 1
294  %cmp2 = fcmp olt double %iv.fp, 1.000000e+04
295  br i1 %cmp2, label %bb, label %return
296
297return:		; preds = %bb
298  ret void
299}
300
301define void @fcmp2() nounwind {
302; CHECK-LABEL: @fcmp2(
303; CHECK-NEXT:  entry:
304; CHECK-NEXT:    br label [[BB:%.*]]
305; CHECK:       bb:
306; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
307; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IV]], 2000
308; CHECK-NEXT:    br i1 [[CMP1]], label [[BACKEDGE]], label [[RETURN:%.*]]
309; CHECK:       backedge:
310; CHECK-NEXT:    [[IV_FP:%.*]] = sitofp i64 [[IV]] to double
311; CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @foo(double [[IV_FP]]) [[ATTR0]]
312; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
313; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt double [[IV_FP]], 1.000000e+04
314; CHECK-NEXT:    br i1 [[CMP2]], label [[BB]], label [[RETURN]]
315; CHECK:       return:
316; CHECK-NEXT:    ret void
317;
318entry:
319  br label %bb
320
321bb:		; preds = %bb, %entry
322  %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
323  %cmp1 = icmp slt i64 %iv, 2000
324  br i1 %cmp1, label %backedge, label %return
325
326backedge:
327  %iv.fp = sitofp i64 %iv to double
328  tail call i32 @foo(double %iv.fp) nounwind
329  %iv.next = add nsw nuw i64 %iv, 1
330  %cmp2 = fcmp olt double %iv.fp, 1.000000e+04
331  br i1 %cmp2, label %bb, label %return
332
333return:		; preds = %bb
334  ret void
335}
336
337define void @fcmp_neg1() nounwind {
338; CHECK-LABEL: @fcmp_neg1(
339; CHECK-NEXT:  entry:
340; CHECK-NEXT:    br label [[BB:%.*]]
341; CHECK:       bb:
342; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
343; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IV]], -20
344; CHECK-NEXT:    br i1 [[CMP1]], label [[BACKEDGE]], label [[RETURN:%.*]]
345; CHECK:       backedge:
346; CHECK-NEXT:    [[IV_FP:%.*]] = sitofp i64 [[IV]] to double
347; CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @foo(double [[IV_FP]]) [[ATTR0]]
348; CHECK-NEXT:    [[IV_NEXT]] = add nuw i64 [[IV]], 1
349; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt double [[IV_FP]], 1.000000e+04
350; CHECK-NEXT:    br i1 [[CMP2]], label [[BB]], label [[RETURN]]
351; CHECK:       return:
352; CHECK-NEXT:    ret void
353;
354entry:
355  br label %bb
356
357bb:		; preds = %bb, %entry
358  %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
359  ;; Range fact outside precise integer region
360  %cmp1 = icmp ult i64 %iv, -20
361  br i1 %cmp1, label %backedge, label %return
362
363backedge:
364  %iv.fp = sitofp i64 %iv to double
365  tail call i32 @foo(double %iv.fp) nounwind
366  %iv.next = add nuw i64 %iv, 1
367  %cmp2 = fcmp olt double %iv.fp, 1.000000e+04
368  br i1 %cmp2, label %bb, label %return
369
370return:		; preds = %bb
371  ret void
372}
373