Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / IndVarSimplify / iv-poison.ll
blob383599f6143575d348d3f63dd0157f2e057d80a5
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=indvars -S < %s | FileCheck %s
4 ; PR59777
5 define i2 @iv_hoist_nsw_poison(i2 %arg) {
6 ; CHECK-LABEL: @iv_hoist_nsw_poison(
7 ; CHECK-NEXT:  bb:
8 ; CHECK-NEXT:    br label [[BB1:%.*]]
9 ; CHECK:       bb1:
10 ; CHECK-NEXT:    [[DOT07:%.*]] = phi i2 [ 1, [[BB:%.*]] ], [ [[I:%.*]], [[BB1]] ]
11 ; CHECK-NEXT:    [[I]] = add nuw i2 [[DOT07]], 1
12 ; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ult i2 1, [[ARG:%.*]]
13 ; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[COMMON_RET:%.*]], label [[BB1]]
14 ; CHECK:       common.ret:
15 ; CHECK-NEXT:    [[I2_LCSSA:%.*]] = phi i2 [ [[I]], [[BB1]] ]
16 ; CHECK-NEXT:    ret i2 [[I2_LCSSA]]
18 bb:
19   br label %bb1
21 bb1:                                              ; preds = %bb1, %bb
22   %.07 = phi i2 [ 1, %bb ], [ %i, %bb1 ]
23   %.0 = phi i2 [ 1, %bb ], [ %i2, %bb1 ]
24   %i = add nsw i2 %.07, 1
25   %i2 = add i2 %.0, 1
26   %.not.not = icmp ult i2 %.07, %arg
27   br i1 %.not.not, label %common.ret, label %bb1
29 common.ret:                                       ; preds = %bb1
30   ret i2 %i2
33 define i4 @iv_hoist_nsw_poison2(i4 %0, i4 %end, i4 %start) {
34 ; CHECK-LABEL: @iv_hoist_nsw_poison2(
35 ; CHECK-NEXT:  entry:
36 ; CHECK-NEXT:    br label [[LOOP:%.*]]
37 ; CHECK:       loop:
38 ; CHECK-NEXT:    [[IV_0:%.*]] = phi i4 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
39 ; CHECK-NEXT:    [[IV_0_NEXT]] = add i4 [[IV_0]], 1
40 ; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ult i4 [[IV_0]], [[END:%.*]]
41 ; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
42 ; CHECK:       exit:
43 ; CHECK-NEXT:    [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
44 ; CHECK-NEXT:    ret i4 [[IV_1_NEXT_LCSSA]]
46 entry:
47   br label %loop
49 loop:
50   %iv.0 = phi i4 [ %start, %entry ], [ %iv.0.next, %loop ]
51   %iv.1 = phi i4 [ %start, %entry ], [ %iv.1.next, %loop ]
52   %iv.0.next = add i4 %iv.0, 1
53   %iv.1.next = add nsw i4 %iv.1, 1
54   %.not.not = icmp ult i4 %iv.0, %end
55   br i1 %.not.not, label %exit, label %loop
57 exit:
58   ret i4 %iv.1.next
61 define i2 @iv_hoist_both_adds_nsw(i2 %arg) {
62 ; CHECK-LABEL: @iv_hoist_both_adds_nsw(
63 ; CHECK-NEXT:  bb:
64 ; CHECK-NEXT:    br label [[LOOP:%.*]]
65 ; CHECK:       loop:
66 ; CHECK-NEXT:    [[IV_0:%.*]] = phi i2 [ 1, [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
67 ; CHECK-NEXT:    [[IV_0_NEXT]] = add nuw nsw i2 [[IV_0]], 1
68 ; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ult i2 1, [[ARG:%.*]]
69 ; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
70 ; CHECK:       exit:
71 ; CHECK-NEXT:    [[IV_1_NEXT_LCSSA:%.*]] = phi i2 [ [[IV_0_NEXT]], [[LOOP]] ]
72 ; CHECK-NEXT:    ret i2 [[IV_1_NEXT_LCSSA]]
74 bb:
75   br label %loop
77 loop:
78   %iv.0 = phi i2 [ 1, %bb ], [ %iv.0.next, %loop ]
79   %iv.1 = phi i2 [ 1, %bb ], [ %iv.1.next, %loop ]
80   %iv.0.next = add nsw i2 %iv.0, 1
81   %iv.1.next = add nsw i2 %iv.1, 1
82   %.not.not = icmp ult i2 %iv.0, %arg
83   br i1 %.not.not, label %exit, label %loop
85 exit:
86   ret i2 %iv.1.next
89 define i4 @iv_hoist_both_adds_nsw_extra_use(i4 %arg) {
90 ; CHECK-LABEL: @iv_hoist_both_adds_nsw_extra_use(
91 ; CHECK-NEXT:  bb:
92 ; CHECK-NEXT:    br label [[LOOP:%.*]]
93 ; CHECK:       loop:
94 ; CHECK-NEXT:    [[IV_0:%.*]] = phi i4 [ 1, [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
95 ; CHECK-NEXT:    [[IV_0_NEXT]] = add nuw nsw i4 [[IV_0]], 1
96 ; CHECK-NEXT:    call void @use(i4 [[IV_0_NEXT]])
97 ; CHECK-NEXT:    call void @use(i4 [[IV_0_NEXT]])
98 ; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ult i4 1, [[ARG:%.*]]
99 ; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
100 ; CHECK:       exit:
101 ; CHECK-NEXT:    [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
102 ; CHECK-NEXT:    ret i4 [[IV_1_NEXT_LCSSA]]
105   br label %loop
107 loop:
108   %iv.0 = phi i4 [ 1, %bb ], [ %iv.0.next, %loop ]
109   %iv.1 = phi i4 [ 1, %bb ], [ %iv.1.next, %loop ]
110   %iv.0.next = add nsw i4 %iv.0, 1
111   call void @use(i4 %iv.0.next)
112   %iv.1.next = add nsw i4 %iv.1, 1
113   call void @use(i4 %iv.1.next)
114   %.not.not = icmp ult i4 %iv.0, %arg
115   br i1 %.not.not, label %exit, label %loop
117 exit:
118   ret i4 %iv.1.next
121 define i4 @iv_hoist_both_adds_nsw_extra_use_incs_reordered(i4 %arg) {
122 ; CHECK-LABEL: @iv_hoist_both_adds_nsw_extra_use_incs_reordered(
123 ; CHECK-NEXT:  bb:
124 ; CHECK-NEXT:    br label [[LOOP:%.*]]
125 ; CHECK:       loop:
126 ; CHECK-NEXT:    [[IV_0:%.*]] = phi i4 [ 1, [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
127 ; CHECK-NEXT:    [[IV_0_NEXT]] = add nuw nsw i4 [[IV_0]], 1
128 ; CHECK-NEXT:    call void @use(i4 [[IV_0_NEXT]])
129 ; CHECK-NEXT:    call void @use(i4 [[IV_0_NEXT]])
130 ; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ult i4 1, [[ARG:%.*]]
131 ; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
132 ; CHECK:       exit:
133 ; CHECK-NEXT:    [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
134 ; CHECK-NEXT:    ret i4 [[IV_1_NEXT_LCSSA]]
137   br label %loop
139 loop:
140   %iv.0 = phi i4 [ 1, %bb ], [ %iv.0.next, %loop ]
141   %iv.1 = phi i4 [ 1, %bb ], [ %iv.1.next, %loop ]
142   %iv.1.next = add nsw i4 %iv.1, 1
143   call void @use(i4 %iv.1.next)
144   %iv.0.next = add nsw i4 %iv.0, 1
145   call void @use(i4 %iv.0.next)
146   %.not.not = icmp ult i4 %iv.0, %arg
147   br i1 %.not.not, label %exit, label %loop
149 exit:
150   ret i4 %iv.1.next
153 define i4 @iv_hoist_nsw_poison_extra_use(i4 %0, i4 %end, i4 %start) {
154 ; CHECK-LABEL: @iv_hoist_nsw_poison_extra_use(
155 ; CHECK-NEXT:  entry:
156 ; CHECK-NEXT:    br label [[LOOP:%.*]]
157 ; CHECK:       loop:
158 ; CHECK-NEXT:    [[IV_0:%.*]] = phi i4 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
159 ; CHECK-NEXT:    [[IV_0_NEXT]] = add i4 [[IV_0]], 1
160 ; CHECK-NEXT:    call void @use(i4 [[IV_0_NEXT]])
161 ; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ult i4 [[IV_0]], [[END:%.*]]
162 ; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
163 ; CHECK:       exit:
164 ; CHECK-NEXT:    [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
165 ; CHECK-NEXT:    ret i4 [[IV_1_NEXT_LCSSA]]
167 entry:
168   br label %loop
170 loop:
171   %iv.0 = phi i4 [ %start, %entry ], [ %iv.0.next, %loop ]
172   %iv.1 = phi i4 [ %start, %entry ], [ %iv.1.next, %loop ]
173   %iv.0.next = add i4 %iv.0, 1
174   call void @use(i4 %iv.0.next)
175   %iv.1.next = add nsw i4 %iv.1, 1
176   %.not.not = icmp ult i4 %iv.0, %end
177   br i1 %.not.not, label %exit, label %loop
179 exit:
180   ret i4 %iv.1.next
183 declare void @use(i4)
185 define i2 @iv_hoist_nuw_poison(i2 %arg, i2 %start) {
186 ; CHECK-LABEL: @iv_hoist_nuw_poison(
187 ; CHECK-NEXT:  bb:
188 ; CHECK-NEXT:    br label [[BB1:%.*]]
189 ; CHECK:       bb1:
190 ; CHECK-NEXT:    [[DOT07:%.*]] = phi i2 [ [[START:%.*]], [[BB:%.*]] ], [ [[I:%.*]], [[BB1]] ]
191 ; CHECK-NEXT:    [[I]] = add i2 [[DOT07]], 1
192 ; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ult i2 [[START]], [[ARG:%.*]]
193 ; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[COMMON_RET:%.*]], label [[BB1]]
194 ; CHECK:       common.ret:
195 ; CHECK-NEXT:    [[I2_LCSSA:%.*]] = phi i2 [ [[I]], [[BB1]] ]
196 ; CHECK-NEXT:    ret i2 [[I2_LCSSA]]
199   br label %bb1
201 bb1:                                              ; preds = %bb1, %bb
202   %.07 = phi i2 [ %start, %bb ], [ %i, %bb1 ]
203   %.0 = phi i2 [ %start, %bb ], [ %i2, %bb1 ]
204   %i = add nuw i2 %.07, 1
205   %i2 = add i2 %.0, 1
206   %.not.not = icmp ult i2 %.07, %arg
207   br i1 %.not.not, label %common.ret, label %bb1
209 common.ret:                                       ; preds = %bb1
210   ret i2 %i2
213 define i4 @iv_hoist_nuw_poison2(i4 %0, i4 %end, i4 %start) {
214 ; CHECK-LABEL: @iv_hoist_nuw_poison2(
215 ; CHECK-NEXT:  entry:
216 ; CHECK-NEXT:    br label [[LOOP:%.*]]
217 ; CHECK:       loop:
218 ; CHECK-NEXT:    [[IV_0:%.*]] = phi i4 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
219 ; CHECK-NEXT:    [[IV_0_NEXT]] = add i4 [[IV_0]], 1
220 ; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ult i4 [[START]], [[END:%.*]]
221 ; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
222 ; CHECK:       exit:
223 ; CHECK-NEXT:    [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
224 ; CHECK-NEXT:    ret i4 [[IV_1_NEXT_LCSSA]]
226 entry:
227   br label %loop
229 loop:
230   %iv.0 = phi i4 [ %start, %entry ], [ %iv.0.next, %loop ]
231   %iv.1 = phi i4 [ %start, %entry ], [ %iv.1.next, %loop ]
232   %iv.0.next = add i4 %iv.0, 1
233   %iv.1.next = add nuw i4 %iv.1, 1
234   %.not.not = icmp ult i4 %iv.0, %end
235   br i1 %.not.not, label %exit, label %loop
237 exit:
238   ret i4 %iv.1.next
241 define i2 @iv_hoist_both_adds_nuw(i2 %arg, i2 %start) {
242 ; CHECK-LABEL: @iv_hoist_both_adds_nuw(
243 ; CHECK-NEXT:  bb:
244 ; CHECK-NEXT:    br label [[LOOP:%.*]]
245 ; CHECK:       loop:
246 ; CHECK-NEXT:    [[IV_0:%.*]] = phi i2 [ [[START:%.*]], [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
247 ; CHECK-NEXT:    [[IV_0_NEXT]] = add nuw i2 [[IV_0]], 1
248 ; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ult i2 [[START]], [[ARG:%.*]]
249 ; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
250 ; CHECK:       exit:
251 ; CHECK-NEXT:    [[IV_1_NEXT_LCSSA:%.*]] = phi i2 [ [[IV_0_NEXT]], [[LOOP]] ]
252 ; CHECK-NEXT:    ret i2 [[IV_1_NEXT_LCSSA]]
255   br label %loop
257 loop:
258   %iv.0 = phi i2 [ %start, %bb ], [ %iv.0.next, %loop ]
259   %iv.1 = phi i2 [ %start, %bb ], [ %iv.1.next, %loop ]
260   %iv.0.next = add nuw i2 %iv.0, 1
261   %iv.1.next = add nuw i2 %iv.1, 1
262   %.not.not = icmp ult i2 %iv.0, %arg
263   br i1 %.not.not, label %exit, label %loop
265 exit:
266   ret i2 %iv.1.next
269 define i4 @iv_hoist_both_adds_nuw_extra_use(i4 %arg, i4 %start) {
270 ; CHECK-LABEL: @iv_hoist_both_adds_nuw_extra_use(
271 ; CHECK-NEXT:  bb:
272 ; CHECK-NEXT:    br label [[LOOP:%.*]]
273 ; CHECK:       loop:
274 ; CHECK-NEXT:    [[IV_0:%.*]] = phi i4 [ [[START:%.*]], [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
275 ; CHECK-NEXT:    [[IV_0_NEXT]] = add nuw i4 [[IV_0]], 1
276 ; CHECK-NEXT:    call void @use(i4 [[IV_0_NEXT]])
277 ; CHECK-NEXT:    call void @use(i4 [[IV_0_NEXT]])
278 ; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ult i4 [[START]], [[ARG:%.*]]
279 ; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
280 ; CHECK:       exit:
281 ; CHECK-NEXT:    [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
282 ; CHECK-NEXT:    ret i4 [[IV_1_NEXT_LCSSA]]
285   br label %loop
287 loop:
288   %iv.0 = phi i4 [ %start, %bb ], [ %iv.0.next, %loop ]
289   %iv.1 = phi i4 [ %start, %bb ], [ %iv.1.next, %loop ]
290   %iv.0.next = add nuw i4 %iv.0, 1
291   call void @use(i4 %iv.0.next)
292   %iv.1.next = add nuw i4 %iv.1, 1
293   call void @use(i4 %iv.1.next)
294   %.not.not = icmp ult i4 %iv.0, %arg
295   br i1 %.not.not, label %exit, label %loop
297 exit:
298   ret i4 %iv.1.next
301 define i4 @iv_hoist_both_adds_nuw_extra_use_incs_reordered(i4 %arg, i4 %start) {
302 ; CHECK-LABEL: @iv_hoist_both_adds_nuw_extra_use_incs_reordered(
303 ; CHECK-NEXT:  bb:
304 ; CHECK-NEXT:    br label [[LOOP:%.*]]
305 ; CHECK:       loop:
306 ; CHECK-NEXT:    [[IV_0:%.*]] = phi i4 [ [[START:%.*]], [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
307 ; CHECK-NEXT:    [[IV_0_NEXT]] = add nuw i4 [[IV_0]], 1
308 ; CHECK-NEXT:    call void @use(i4 [[IV_0_NEXT]])
309 ; CHECK-NEXT:    call void @use(i4 [[IV_0_NEXT]])
310 ; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ult i4 [[START]], [[ARG:%.*]]
311 ; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
312 ; CHECK:       exit:
313 ; CHECK-NEXT:    [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
314 ; CHECK-NEXT:    ret i4 [[IV_1_NEXT_LCSSA]]
317   br label %loop
319 loop:
320   %iv.0 = phi i4 [ %start, %bb ], [ %iv.0.next, %loop ]
321   %iv.1 = phi i4 [ %start, %bb ], [ %iv.1.next, %loop ]
322   %iv.1.next = add nuw i4 %iv.1, 1
323   call void @use(i4 %iv.1.next)
324   %iv.0.next = add nuw i4 %iv.0, 1
325   call void @use(i4 %iv.0.next)
326   %.not.not = icmp ult i4 %iv.0, %arg
327   br i1 %.not.not, label %exit, label %loop
329 exit:
330   ret i4 %iv.1.next
333 define i4 @iv_hoist_nuw_poison_extra_use(i4 %0, i4 %end, i4 %start) {
334 ; CHECK-LABEL: @iv_hoist_nuw_poison_extra_use(
335 ; CHECK-NEXT:  entry:
336 ; CHECK-NEXT:    br label [[LOOP:%.*]]
337 ; CHECK:       loop:
338 ; CHECK-NEXT:    [[IV_0:%.*]] = phi i4 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
339 ; CHECK-NEXT:    [[IV_0_NEXT]] = add i4 [[IV_0]], 1
340 ; CHECK-NEXT:    call void @use(i4 [[IV_0_NEXT]])
341 ; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ult i4 [[START]], [[END:%.*]]
342 ; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
343 ; CHECK:       exit:
344 ; CHECK-NEXT:    [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
345 ; CHECK-NEXT:    ret i4 [[IV_1_NEXT_LCSSA]]
347 entry:
348   br label %loop
350 loop:
351   %iv.0 = phi i4 [ %start, %entry ], [ %iv.0.next, %loop ]
352   %iv.1 = phi i4 [ %start, %entry ], [ %iv.1.next, %loop ]
353   %iv.0.next = add i4 %iv.0, 1
354   call void @use(i4 %iv.0.next)
355   %iv.1.next = add nuw i4 %iv.1, 1
356   %.not.not = icmp ult i4 %iv.0, %end
357   br i1 %.not.not, label %exit, label %loop
359 exit:
360   ret i4 %iv.1.next