1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=indvars -S < %s | FileCheck %s
5 define i2 @iv_hoist_nsw_poison(i2 %arg) {
6 ; CHECK-LABEL: @iv_hoist_nsw_poison(
8 ; CHECK-NEXT: br label [[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]]
15 ; CHECK-NEXT: [[I2_LCSSA:%.*]] = phi i2 [ [[I]], [[BB1]] ]
16 ; CHECK-NEXT: ret i2 [[I2_LCSSA]]
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
26 %.not.not = icmp ult i2 %.07, %arg
27 br i1 %.not.not, label %common.ret, label %bb1
29 common.ret: ; preds = %bb1
33 define i4 @iv_hoist_nsw_poison2(i4 %0, i4 %end, i4 %start) {
34 ; CHECK-LABEL: @iv_hoist_nsw_poison2(
36 ; CHECK-NEXT: br label [[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]]
43 ; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
44 ; CHECK-NEXT: ret i4 [[IV_1_NEXT_LCSSA]]
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
61 define i2 @iv_hoist_both_adds_nsw(i2 %arg) {
62 ; CHECK-LABEL: @iv_hoist_both_adds_nsw(
64 ; CHECK-NEXT: br label [[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]]
71 ; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i2 [ [[IV_0_NEXT]], [[LOOP]] ]
72 ; CHECK-NEXT: ret i2 [[IV_1_NEXT_LCSSA]]
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
89 define i4 @iv_hoist_both_adds_nsw_extra_use(i4 %arg) {
90 ; CHECK-LABEL: @iv_hoist_both_adds_nsw_extra_use(
92 ; CHECK-NEXT: br label [[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]]
101 ; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
102 ; CHECK-NEXT: ret i4 [[IV_1_NEXT_LCSSA]]
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
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(
124 ; CHECK-NEXT: br label [[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]]
133 ; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
134 ; CHECK-NEXT: ret i4 [[IV_1_NEXT_LCSSA]]
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
153 define i4 @iv_hoist_nsw_poison_extra_use(i4 %0, i4 %end, i4 %start) {
154 ; CHECK-LABEL: @iv_hoist_nsw_poison_extra_use(
156 ; CHECK-NEXT: br label [[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]]
164 ; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
165 ; CHECK-NEXT: ret i4 [[IV_1_NEXT_LCSSA]]
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
183 declare void @use(i4)
185 define i2 @iv_hoist_nuw_poison(i2 %arg, i2 %start) {
186 ; CHECK-LABEL: @iv_hoist_nuw_poison(
188 ; CHECK-NEXT: br label [[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]]
195 ; CHECK-NEXT: [[I2_LCSSA:%.*]] = phi i2 [ [[I]], [[BB1]] ]
196 ; CHECK-NEXT: ret i2 [[I2_LCSSA]]
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
206 %.not.not = icmp ult i2 %.07, %arg
207 br i1 %.not.not, label %common.ret, label %bb1
209 common.ret: ; preds = %bb1
213 define i4 @iv_hoist_nuw_poison2(i4 %0, i4 %end, i4 %start) {
214 ; CHECK-LABEL: @iv_hoist_nuw_poison2(
216 ; CHECK-NEXT: br label [[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]]
223 ; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
224 ; CHECK-NEXT: ret i4 [[IV_1_NEXT_LCSSA]]
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
241 define i2 @iv_hoist_both_adds_nuw(i2 %arg, i2 %start) {
242 ; CHECK-LABEL: @iv_hoist_both_adds_nuw(
244 ; CHECK-NEXT: br label [[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]]
251 ; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i2 [ [[IV_0_NEXT]], [[LOOP]] ]
252 ; CHECK-NEXT: ret i2 [[IV_1_NEXT_LCSSA]]
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
269 define i4 @iv_hoist_both_adds_nuw_extra_use(i4 %arg, i4 %start) {
270 ; CHECK-LABEL: @iv_hoist_both_adds_nuw_extra_use(
272 ; CHECK-NEXT: br label [[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]]
281 ; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
282 ; CHECK-NEXT: ret i4 [[IV_1_NEXT_LCSSA]]
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
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(
304 ; CHECK-NEXT: br label [[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]]
313 ; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
314 ; CHECK-NEXT: ret i4 [[IV_1_NEXT_LCSSA]]
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
333 define i4 @iv_hoist_nuw_poison_extra_use(i4 %0, i4 %end, i4 %start) {
334 ; CHECK-LABEL: @iv_hoist_nuw_poison_extra_use(
336 ; CHECK-NEXT: br label [[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]]
344 ; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
345 ; CHECK-NEXT: ret i4 [[IV_1_NEXT_LCSSA]]
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