xref: /llvm-project/llvm/test/Transforms/IndVarSimplify/infer-poison-flags.ll (revision 864bb84a427de367528d15270790dd152871daf2)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=indvars -S | FileCheck %s
3
4@A = external global i32
5
6define void @add_cr_nsw_nuw() {
7; CHECK-LABEL: @add_cr_nsw_nuw(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    br label [[LOOP:%.*]]
10; CHECK:       loop:
11; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
12; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1
13; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
14; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1000
15; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
16; CHECK:       loopexit:
17; CHECK-NEXT:    ret void
18;
19entry:
20  br label %loop
21
22loop:
23  %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
24  %i.next = add i32 %i, 1
25  store i32 %i, ptr @A
26  %c = icmp ne i32 %i.next, 1000
27  br i1 %c, label %loop, label %loopexit
28
29loopexit:
30  ret void
31}
32
33define void @add_cr_nuw() {
34; CHECK-LABEL: @add_cr_nuw(
35; CHECK-NEXT:  entry:
36; CHECK-NEXT:    br label [[LOOP:%.*]]
37; CHECK:       loop:
38; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
39; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
40; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
41; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], -1
42; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
43; CHECK:       loopexit:
44; CHECK-NEXT:    ret void
45;
46entry:
47  br label %loop
48
49loop:
50  %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
51  %i.next = add i32 %i, 1
52  store i32 %i, ptr @A
53  %c = icmp ne i32 %i.next, -1
54  br i1 %c, label %loop, label %loopexit
55
56loopexit:
57  ret void
58}
59
60define void @add_cr_nsw() {
61; CHECK-LABEL: @add_cr_nsw(
62; CHECK-NEXT:  entry:
63; CHECK-NEXT:    br label [[LOOP:%.*]]
64; CHECK:       loop:
65; CHECK-NEXT:    [[I:%.*]] = phi i32 [ -10, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
66; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
67; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
68; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], 10
69; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
70; CHECK:       loopexit:
71; CHECK-NEXT:    ret void
72;
73entry:
74  br label %loop
75
76loop:
77  %i = phi i32 [ -10, %entry ], [ %i.next, %loop ]
78  %i.next = add i32 %i, 1
79  store i32 %i, ptr @A
80  %c = icmp ne i32 %i.next, 10
81  br i1 %c, label %loop, label %loopexit
82
83loopexit:
84  ret void
85}
86
87define void @add_cr_none() {
88; CHECK-LABEL: @add_cr_none(
89; CHECK-NEXT:  entry:
90; CHECK-NEXT:    br label [[LOOP:%.*]]
91; CHECK:       loop:
92; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 10, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
93; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
94; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
95; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], 0
96; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
97; CHECK:       loopexit:
98; CHECK-NEXT:    ret void
99;
100entry:
101  br label %loop
102
103loop:
104  %i = phi i32 [ 10, %entry ], [ %i.next, %loop ]
105  %i.next = add i32 %i, 1
106  store i32 %i, ptr @A
107  %c = icmp ne i32 %i.next, 0
108  br i1 %c, label %loop, label %loopexit
109
110loopexit:
111  ret void
112}
113
114define void @add_unknown_none(i32 %n) {
115; CHECK-LABEL: @add_unknown_none(
116; CHECK-NEXT:  entry:
117; CHECK-NEXT:    br label [[LOOP:%.*]]
118; CHECK:       loop:
119; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
120; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
121; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
122; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], [[N:%.*]]
123; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
124; CHECK:       loopexit:
125; CHECK-NEXT:    ret void
126;
127entry:
128  br label %loop
129
130loop:
131  %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
132  %i.next = add i32 %i, 1
133  store i32 %i, ptr @A
134  %c = icmp ne i32 %i.next, %n
135  br i1 %c, label %loop, label %loopexit
136
137loopexit:
138  ret void
139}
140
141define void @sub_cr_nsw_nuw() {
142; CHECK-LABEL: @sub_cr_nsw_nuw(
143; CHECK-NEXT:  entry:
144; CHECK-NEXT:    br label [[LOOP:%.*]]
145; CHECK:       loop:
146; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
147; CHECK-NEXT:    [[I_NEXT]] = sub nsw i32 [[I]], -1
148; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
149; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1000
150; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
151; CHECK:       loopexit:
152; CHECK-NEXT:    ret void
153;
154entry:
155  br label %loop
156
157loop:
158  %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
159  %i.next = sub i32 %i, -1
160  store i32 %i, ptr @A
161  %c = icmp ne i32 %i.next, 1000
162  br i1 %c, label %loop, label %loopexit
163
164loopexit:
165  ret void
166}
167
168
169define void @sub_unknown_none(i32 %n) {
170; CHECK-LABEL: @sub_unknown_none(
171; CHECK-NEXT:  entry:
172; CHECK-NEXT:    br label [[LOOP:%.*]]
173; CHECK:       loop:
174; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
175; CHECK-NEXT:    [[I_NEXT]] = sub i32 [[I]], -1
176; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
177; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], [[N:%.*]]
178; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
179; CHECK:       loopexit:
180; CHECK-NEXT:    ret void
181;
182entry:
183  br label %loop
184
185loop:
186  %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
187  %i.next = sub i32 %i, -1
188  store i32 %i, ptr @A
189  %c = icmp ne i32 %i.next, %n
190  br i1 %c, label %loop, label %loopexit
191
192loopexit:
193  ret void
194}
195
196
197; NOTE: For the rest of these, it looks like we're failing to use a statically
198; computable backedge taken count to infer a range on the IV and thus fail to
199; prove flags via constant range reasoning.
200
201; TODO
202define void @mul_cr_nsw_nuw() {
203; CHECK-LABEL: @mul_cr_nsw_nuw(
204; CHECK-NEXT:  entry:
205; CHECK-NEXT:    br label [[LOOP:%.*]]
206; CHECK:       loop:
207; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
208; CHECK-NEXT:    [[I_NEXT]] = mul i32 [[I]], 2
209; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
210; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1024
211; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
212; CHECK:       loopexit:
213; CHECK-NEXT:    ret void
214;
215entry:
216  br label %loop
217
218loop:
219  %i = phi i32 [ 1, %entry ], [ %i.next, %loop ]
220  %i.next = mul i32 %i, 2
221  store i32 %i, ptr @A
222  %c = icmp ne i32 %i.next, 1024
223  br i1 %c, label %loop, label %loopexit
224
225loopexit:
226  ret void
227}
228
229;; TODO
230define void @shl_cr_nsw_nuw() {
231; CHECK-LABEL: @shl_cr_nsw_nuw(
232; CHECK-NEXT:  entry:
233; CHECK-NEXT:    br label [[LOOP:%.*]]
234; CHECK:       loop:
235; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
236; CHECK-NEXT:    [[I_NEXT]] = shl i32 [[I]], 1
237; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
238; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1024
239; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
240; CHECK:       loopexit:
241; CHECK-NEXT:    ret void
242;
243entry:
244  br label %loop
245
246loop:
247  %i = phi i32 [ 1, %entry ], [ %i.next, %loop ]
248  %i.next = shl i32 %i, 1
249  store i32 %i, ptr @A
250  %c = icmp ne i32 %i.next, 1024
251  br i1 %c, label %loop, label %loopexit
252
253loopexit:
254  ret void
255}
256
257; TODO
258define void @lshr_cr_nsw_nuw() {
259; CHECK-LABEL: @lshr_cr_nsw_nuw(
260; CHECK-NEXT:  entry:
261; CHECK-NEXT:    br label [[LOOP:%.*]]
262; CHECK:       loop:
263; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 1024, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
264; CHECK-NEXT:    [[I_NEXT]] = lshr i32 [[I]], 1
265; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
266; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], 0
267; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
268; CHECK:       loopexit:
269; CHECK-NEXT:    ret void
270;
271entry:
272  br label %loop
273
274loop:
275  %i = phi i32 [ 1024, %entry ], [ %i.next, %loop ]
276  %i.next = lshr i32 %i, 1
277  store i32 %i, ptr @A
278  %c = icmp ne i32 %i.next, 0
279  br i1 %c, label %loop, label %loopexit
280
281loopexit:
282  ret void
283}
284
285; TODO
286define void @lshr_cr_nuw() {
287; CHECK-LABEL: @lshr_cr_nuw(
288; CHECK-NEXT:  entry:
289; CHECK-NEXT:    br label [[LOOP:%.*]]
290; CHECK:       loop:
291; CHECK-NEXT:    [[I:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
292; CHECK-NEXT:    [[I_NEXT]] = lshr i32 [[I]], 1
293; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
294; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], 0
295; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
296; CHECK:       loopexit:
297; CHECK-NEXT:    ret void
298;
299entry:
300  br label %loop
301
302loop:
303  %i = phi i32 [ -1, %entry ], [ %i.next, %loop ]
304  %i.next = lshr i32 %i, 1
305  store i32 %i, ptr @A
306  %c = icmp ne i32 %i.next, 0
307  br i1 %c, label %loop, label %loopexit
308
309loopexit:
310  ret void
311}
312
313; TODO
314define void @ashr_cr_nsw_nuw() {
315; CHECK-LABEL: @ashr_cr_nsw_nuw(
316; CHECK-NEXT:  entry:
317; CHECK-NEXT:    br label [[LOOP:%.*]]
318; CHECK:       loop:
319; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 1024, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
320; CHECK-NEXT:    [[I_NEXT]] = ashr i32 [[I]], 1
321; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
322; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], 0
323; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
324; CHECK:       loopexit:
325; CHECK-NEXT:    ret void
326;
327entry:
328  br label %loop
329
330loop:
331  %i = phi i32 [ 1024, %entry ], [ %i.next, %loop ]
332  %i.next = ashr i32 %i, 1
333  store i32 %i, ptr @A
334  %c = icmp ne i32 %i.next, 0
335  br i1 %c, label %loop, label %loopexit
336
337loopexit:
338  ret void
339}
340
341; TODO
342define void @ashr_cr_nsw() {
343; CHECK-LABEL: @ashr_cr_nsw(
344; CHECK-NEXT:  entry:
345; CHECK-NEXT:    br label [[LOOP:%.*]]
346; CHECK:       loop:
347; CHECK-NEXT:    [[I:%.*]] = phi i32 [ -1024, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
348; CHECK-NEXT:    [[I_NEXT]] = ashr i32 [[I]], 1
349; CHECK-NEXT:    store i32 [[I]], ptr @A, align 4
350; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1
351; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
352; CHECK:       loopexit:
353; CHECK-NEXT:    ret void
354;
355entry:
356  br label %loop
357
358loop:
359  %i = phi i32 [ -1024, %entry ], [ %i.next, %loop ]
360  %i.next = ashr i32 %i, 1
361  store i32 %i, ptr @A
362  %c = icmp ne i32 %i.next, 1
363  br i1 %c, label %loop, label %loopexit
364
365loopexit:
366  ret void
367}
368
369
370