1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=indvars -S < %s -indvars-predicate-loops=0 | FileCheck %s
4 ; A collection of tests which domonstrate cases where we can use properties
5 ; of the loop (i.e. single exit, finite, mustprogress) to optimize conditions
6 ; and extends we couldn't otherwise handle.
8 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
10 define void @slt_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
11 ; CHECK-LABEL: @slt_constant_rhs(
13 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
14 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
16 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
17 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
18 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[TMP0]]
19 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
21 ; CHECK-NEXT: ret void
26 for.body: ; preds = %entry, %for.body
27 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
28 %iv.next = add i8 %iv, 1
29 %zext = zext i8 %iv.next to i16
30 %cmp = icmp slt i16 %zext, 254
31 br i1 %cmp, label %for.body, label %for.end
33 for.end: ; preds = %for.body, %entry
37 ;; Range logic doesn't depend on must execute
38 define void @slt_constant_rhs_maythrow(i16 %n.raw, i8 %start) mustprogress {
39 ; CHECK-LABEL: @slt_constant_rhs_maythrow(
41 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
42 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
44 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
45 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
46 ; CHECK-NEXT: call void @unknown()
47 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[TMP0]]
48 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
50 ; CHECK-NEXT: ret void
55 for.body: ; preds = %entry, %for.body
56 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
57 %iv.next = add i8 %iv, 1
59 %zext = zext i8 %iv.next to i16
60 %cmp = icmp slt i16 %zext, 254
61 br i1 %cmp, label %for.body, label %for.end
63 for.end: ; preds = %for.body, %entry
67 ;; Range logic doesn't depend on must execute
68 define void @slt_constant_rhs_multiexit(i16 %n.raw, i8 %start, i1 %c) mustprogress {
69 ; CHECK-LABEL: @slt_constant_rhs_multiexit(
71 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
72 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
74 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
75 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
76 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LATCH]], label [[FOR_END:%.*]]
78 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[TMP0]]
79 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]]
81 ; CHECK-NEXT: ret void
86 for.body: ; preds = %entry, %for.body
87 %iv = phi i8 [ %iv.next, %latch ], [ %start, %entry ]
88 %iv.next = add i8 %iv, 1
89 br i1 %c, label %latch, label %for.end
92 %zext = zext i8 %iv.next to i16
93 %cmp = icmp slt i16 %zext, 254
94 br i1 %cmp, label %for.body, label %for.end
96 for.end: ; preds = %for.body, %entry
100 define void @slt_non_constant_rhs(i16 %n) mustprogress {
101 ; CHECK-LABEL: @slt_non_constant_rhs(
103 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
105 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
106 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
107 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
108 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]]
109 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
111 ; CHECK-NEXT: ret void
116 for.body: ; preds = %entry, %for.body
117 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
118 %iv.next = add i8 %iv, 1
119 %zext = zext i8 %iv.next to i16
120 %cmp = icmp slt i16 %zext, %n
121 br i1 %cmp, label %for.body, label %for.end
123 for.end: ; preds = %for.body, %entry
127 ; Case where we could prove this using range facts, but not must exit reasoning
128 define void @slt_non_constant_rhs_no_mustprogress(i16 %n.raw) {
129 ; CHECK-LABEL: @slt_non_constant_rhs_no_mustprogress(
131 ; CHECK-NEXT: [[N:%.*]] = and i16 [[N_RAW:%.*]], 255
132 ; CHECK-NEXT: [[SMAX:%.*]] = call i16 @llvm.smax.i16(i16 [[N]], i16 1)
133 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
135 ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i16 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
136 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i16 [[INDVARS_IV]], 1
137 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i16 [[INDVARS_IV_NEXT]], [[SMAX]]
138 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
140 ; CHECK-NEXT: ret void
143 %n = and i16 %n.raw, 255
146 for.body: ; preds = %entry, %for.body
147 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
148 %iv.next = add i8 %iv, 1
149 %zext = zext i8 %iv.next to i16
150 %cmp = icmp slt i16 %zext, %n
151 br i1 %cmp, label %for.body, label %for.end
153 for.end: ; preds = %for.body, %entry
157 ; Fact holds for exiting branch, but not for earlier use
158 ; We could recognize the unreachable loop here, but don't currently. Its
159 ; also not terribly interesting, because EarlyCSE will fold condition.
160 define void @slt_neg_multiple_use(i8 %start) mustprogress {
161 ; CHECK-LABEL: @slt_neg_multiple_use(
163 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[START:%.*]] to i16
164 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[ZEXT]], 254
165 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
166 ; CHECK: for.body.preheader:
167 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
169 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
170 ; CHECK: for.end.loopexit:
171 ; CHECK-NEXT: br label [[FOR_END]]
173 ; CHECK-NEXT: ret void
176 %zext = zext i8 %start to i16
177 %cmp = icmp slt i16 %zext, 254
178 br i1 %cmp, label %for.body, label %for.end
180 for.body: ; preds = %entry, %for.body
181 br i1 %cmp, label %for.body, label %for.end
183 for.end: ; preds = %for.body, %entry
187 define void @slt_neg_multiple_use2(i8 %start, i16 %n) mustprogress {
188 ; CHECK-LABEL: @slt_neg_multiple_use2(
190 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[START:%.*]] to i16
191 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]]
192 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
193 ; CHECK: for.body.preheader:
194 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
196 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
197 ; CHECK: for.end.loopexit:
198 ; CHECK-NEXT: br label [[FOR_END]]
200 ; CHECK-NEXT: ret void
203 %zext = zext i8 %start to i16
204 %cmp = icmp slt i16 %zext, %n
205 br i1 %cmp, label %for.body, label %for.end
207 for.body: ; preds = %entry, %for.body
208 br i1 %cmp, label %for.body, label %for.end
210 for.end: ; preds = %for.body, %entry
214 @G = external global i8
216 ; Negative case where the loop could be infinite and make progress
217 define void @slt_neg_well_defined_infinite(i16 %n) mustprogress {
218 ; CHECK-LABEL: @slt_neg_well_defined_infinite(
220 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
222 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
223 ; CHECK-NEXT: store volatile i8 [[IV]], ptr @G, align 1
224 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
225 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
226 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]]
227 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
229 ; CHECK-NEXT: ret void
234 for.body: ; preds = %entry, %for.body
235 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
236 store volatile i8 %iv, ptr @G
237 %iv.next = add i8 %iv, 1
238 %zext = zext i8 %iv.next to i16
239 %cmp = icmp slt i16 %zext, %n
240 br i1 %cmp, label %for.body, label %for.end
242 for.end: ; preds = %for.body, %entry
246 ; Negative case with no mustprogress rsltuirement
247 define void @slt_neg_no_mustprogress(i16 %n) {
248 ; CHECK-LABEL: @slt_neg_no_mustprogress(
250 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
252 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
253 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
254 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
255 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]]
256 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
258 ; CHECK-NEXT: ret void
263 for.body: ; preds = %entry, %for.body
264 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
265 %iv.next = add i8 %iv, 1
266 %zext = zext i8 %iv.next to i16
267 %cmp = icmp slt i16 %zext, %n
268 br i1 %cmp, label %for.body, label %for.end
270 for.end: ; preds = %for.body, %entry
274 declare void @unknown()
276 define void @slt_neg_abnormal_exit(i16 %n) mustprogress {
277 ; CHECK-LABEL: @slt_neg_abnormal_exit(
279 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
281 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
282 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
283 ; CHECK-NEXT: call void @unknown()
284 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
285 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]]
286 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
288 ; CHECK-NEXT: ret void
293 for.body: ; preds = %entry, %for.body
294 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
295 %iv.next = add i8 %iv, 1
297 %zext = zext i8 %iv.next to i16
298 %cmp = icmp slt i16 %zext, %n
299 br i1 %cmp, label %for.body, label %for.end
301 for.end: ; preds = %for.body, %entry
305 ; For the other comparison flavors, we only bother to repeat the positive
306 ; tests since the negative variants are mostly the same.
308 define void @ne_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
309 ; CHECK-LABEL: @ne_constant_rhs(
311 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
313 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
314 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
315 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
316 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[ZEXT]], 254
317 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
319 ; CHECK-NEXT: ret void
324 for.body: ; preds = %entry, %for.body
325 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
326 %iv.next = add i8 %iv, 1
327 %zext = zext i8 %iv.next to i16
328 %cmp = icmp ne i16 %zext, 254
329 br i1 %cmp, label %for.body, label %for.end
331 for.end: ; preds = %for.body, %entry
335 define void @ne_non_constant_rhs(i16 %n) mustprogress {
336 ; CHECK-LABEL: @ne_non_constant_rhs(
338 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
340 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
341 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
342 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
343 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[ZEXT]], [[N:%.*]]
344 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
346 ; CHECK-NEXT: ret void
351 for.body: ; preds = %entry, %for.body
352 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
353 %iv.next = add i8 %iv, 1
354 %zext = zext i8 %iv.next to i16
355 %cmp = icmp ne i16 %zext, %n
356 br i1 %cmp, label %for.body, label %for.end
358 for.end: ; preds = %for.body, %entry
362 define void @eq_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
363 ; CHECK-LABEL: @eq_constant_rhs(
365 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
367 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
368 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
369 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
370 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[ZEXT]], 254
371 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
373 ; CHECK-NEXT: ret void
378 for.body: ; preds = %entry, %for.body
379 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
380 %iv.next = add i8 %iv, 1
381 %zext = zext i8 %iv.next to i16
382 %cmp = icmp eq i16 %zext, 254
383 br i1 %cmp, label %for.body, label %for.end
385 for.end: ; preds = %for.body, %entry
389 define void @eq_non_constant_rhs(i16 %n) mustprogress {
390 ; CHECK-LABEL: @eq_non_constant_rhs(
392 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
394 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
395 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
396 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
397 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[ZEXT]], [[N:%.*]]
398 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
400 ; CHECK-NEXT: ret void
405 for.body: ; preds = %entry, %for.body
406 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
407 %iv.next = add i8 %iv, 1
408 %zext = zext i8 %iv.next to i16
409 %cmp = icmp eq i16 %zext, %n
410 br i1 %cmp, label %for.body, label %for.end
412 for.end: ; preds = %for.body, %entry
416 define void @sgt_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
417 ; CHECK-LABEL: @sgt_constant_rhs(
419 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
420 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
422 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
423 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
424 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[IV_NEXT]], [[TMP0]]
425 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
427 ; CHECK-NEXT: ret void
432 for.body: ; preds = %entry, %for.body
433 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
434 %iv.next = add i8 %iv, 1
435 %zext = zext i8 %iv.next to i16
436 %cmp = icmp sgt i16 %zext, 254
437 br i1 %cmp, label %for.body, label %for.end
439 for.end: ; preds = %for.body, %entry
443 define void @sgt_non_constant_rhs(i16 %n) mustprogress {
444 ; CHECK-LABEL: @sgt_non_constant_rhs(
446 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
448 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
449 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
450 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
451 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[ZEXT]], [[N:%.*]]
452 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
454 ; CHECK-NEXT: ret void
459 for.body: ; preds = %entry, %for.body
460 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
461 %iv.next = add i8 %iv, 1
462 %zext = zext i8 %iv.next to i16
463 %cmp = icmp sgt i16 %zext, %n
464 br i1 %cmp, label %for.body, label %for.end
466 for.end: ; preds = %for.body, %entry
470 define void @sle_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
471 ; CHECK-LABEL: @sle_constant_rhs(
473 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
474 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
476 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
477 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
478 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[IV_NEXT]], [[TMP0]]
479 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
481 ; CHECK-NEXT: ret void
486 for.body: ; preds = %entry, %for.body
487 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
488 %iv.next = add i8 %iv, 1
489 %zext = zext i8 %iv.next to i16
490 %cmp = icmp sle i16 %zext, 254
491 br i1 %cmp, label %for.body, label %for.end
493 for.end: ; preds = %for.body, %entry
497 define void @sle_non_constant_rhs(i16 %n) mustprogress {
498 ; CHECK-LABEL: @sle_non_constant_rhs(
500 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
502 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
503 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
504 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
505 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i16 [[ZEXT]], [[N:%.*]]
506 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
508 ; CHECK-NEXT: ret void
513 for.body: ; preds = %entry, %for.body
514 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
515 %iv.next = add i8 %iv, 1
516 %zext = zext i8 %iv.next to i16
517 %cmp = icmp sle i16 %zext, %n
518 br i1 %cmp, label %for.body, label %for.end
520 for.end: ; preds = %for.body, %entry
524 define void @sge_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
525 ; CHECK-LABEL: @sge_constant_rhs(
527 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
528 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
530 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
531 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
532 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[IV_NEXT]], [[TMP0]]
533 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
535 ; CHECK-NEXT: ret void
540 for.body: ; preds = %entry, %for.body
541 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
542 %iv.next = add i8 %iv, 1
543 %zext = zext i8 %iv.next to i16
544 %cmp = icmp sge i16 %zext, 254
545 br i1 %cmp, label %for.body, label %for.end
547 for.end: ; preds = %for.body, %entry
551 define void @sge_non_constant_rhs(i16 %n) mustprogress {
552 ; CHECK-LABEL: @sge_non_constant_rhs(
554 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
556 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
557 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
558 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
559 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i16 [[ZEXT]], [[N:%.*]]
560 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
562 ; CHECK-NEXT: ret void
567 for.body: ; preds = %entry, %for.body
568 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
569 %iv.next = add i8 %iv, 1
570 %zext = zext i8 %iv.next to i16
571 %cmp = icmp sge i16 %zext, %n
572 br i1 %cmp, label %for.body, label %for.end
574 for.end: ; preds = %for.body, %entry
578 define void @ult_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
579 ; CHECK-LABEL: @ult_constant_rhs(
581 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
582 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
584 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
585 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
586 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[TMP0]]
587 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
589 ; CHECK-NEXT: ret void
594 for.body: ; preds = %entry, %for.body
595 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
596 %iv.next = add i8 %iv, 1
597 %zext = zext i8 %iv.next to i16
598 %cmp = icmp ult i16 %zext, 254
599 br i1 %cmp, label %for.body, label %for.end
601 for.end: ; preds = %for.body, %entry
605 define void @ult_non_constant_rhs(i16 %n) mustprogress {
606 ; CHECK-LABEL: @ult_non_constant_rhs(
608 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
610 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
611 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
612 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
613 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[ZEXT]], [[N:%.*]]
614 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
616 ; CHECK-NEXT: ret void
621 for.body: ; preds = %entry, %for.body
622 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
623 %iv.next = add i8 %iv, 1
624 %zext = zext i8 %iv.next to i16
625 %cmp = icmp ult i16 %zext, %n
626 br i1 %cmp, label %for.body, label %for.end
628 for.end: ; preds = %for.body, %entry
632 define void @ugt_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
633 ; CHECK-LABEL: @ugt_constant_rhs(
635 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
636 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
638 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
639 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
640 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[IV_NEXT]], [[TMP0]]
641 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
643 ; CHECK-NEXT: ret void
648 for.body: ; preds = %entry, %for.body
649 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
650 %iv.next = add i8 %iv, 1
651 %zext = zext i8 %iv.next to i16
652 %cmp = icmp ugt i16 %zext, 254
653 br i1 %cmp, label %for.body, label %for.end
655 for.end: ; preds = %for.body, %entry
659 define void @ugt_neg_non_loop(i16 %n.raw, i8 %start) mustprogress {
660 ; CHECK-LABEL: @ugt_neg_non_loop(
662 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
664 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
665 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
666 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
667 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i16 [[ZEXT]], -2
668 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
670 ; CHECK-NEXT: ret void
675 for.body: ; preds = %entry, %for.body
676 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
677 %iv.next = add i8 %iv, 1
678 %zext = zext i8 %iv.next to i16
679 %cmp = icmp ugt i16 %zext, -2
680 br i1 %cmp, label %for.body, label %for.end
682 for.end: ; preds = %for.body, %entry
686 define void @ugt_non_constant_rhs(i16 %n) mustprogress {
687 ; CHECK-LABEL: @ugt_non_constant_rhs(
689 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
691 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
692 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
693 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
694 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i16 [[ZEXT]], [[N:%.*]]
695 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
697 ; CHECK-NEXT: ret void
702 for.body: ; preds = %entry, %for.body
703 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
704 %iv.next = add i8 %iv, 1
705 %zext = zext i8 %iv.next to i16
706 %cmp = icmp ugt i16 %zext, %n
707 br i1 %cmp, label %for.body, label %for.end
709 for.end: ; preds = %for.body, %entry
713 define void @ule_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
714 ; CHECK-LABEL: @ule_constant_rhs(
716 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
717 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
719 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
720 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
721 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[IV_NEXT]], [[TMP0]]
722 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
724 ; CHECK-NEXT: ret void
729 for.body: ; preds = %entry, %for.body
730 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
731 %iv.next = add i8 %iv, 1
732 %zext = zext i8 %iv.next to i16
733 %cmp = icmp ule i16 %zext, 254
734 br i1 %cmp, label %for.body, label %for.end
736 for.end: ; preds = %for.body, %entry
740 define void @ule_non_constant_rhs(i16 %n) mustprogress {
741 ; CHECK-LABEL: @ule_non_constant_rhs(
743 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
745 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
746 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
747 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
748 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i16 [[ZEXT]], [[N:%.*]]
749 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
751 ; CHECK-NEXT: ret void
756 for.body: ; preds = %entry, %for.body
757 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
758 %iv.next = add i8 %iv, 1
759 %zext = zext i8 %iv.next to i16
760 %cmp = icmp ule i16 %zext, %n
761 br i1 %cmp, label %for.body, label %for.end
763 for.end: ; preds = %for.body, %entry
767 define void @uge_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
768 ; CHECK-LABEL: @uge_constant_rhs(
770 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
771 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
773 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
774 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
775 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[IV_NEXT]], [[TMP0]]
776 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
778 ; CHECK-NEXT: ret void
783 for.body: ; preds = %entry, %for.body
784 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
785 %iv.next = add i8 %iv, 1
786 %zext = zext i8 %iv.next to i16
787 %cmp = icmp uge i16 %zext, 254
788 br i1 %cmp, label %for.body, label %for.end
790 for.end: ; preds = %for.body, %entry
794 define void @uge_non_constant_rhs(i16 %n) mustprogress {
795 ; CHECK-LABEL: @uge_non_constant_rhs(
797 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
799 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
800 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
801 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
802 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[ZEXT]], [[N:%.*]]
803 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
805 ; CHECK-NEXT: ret void
810 for.body: ; preds = %entry, %for.body
811 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
812 %iv.next = add i8 %iv, 1
813 %zext = zext i8 %iv.next to i16
814 %cmp = icmp uge i16 %zext, %n
815 br i1 %cmp, label %for.body, label %for.end
817 for.end: ; preds = %for.body, %entry
821 ; Show that these transformatios also work with inverted operands
822 ; We only both to do this with slt/ult, but it applies to all predicates.
824 define void @slt_constant_lhs(i16 %n.raw, i8 %start) mustprogress {
825 ; CHECK-LABEL: @slt_constant_lhs(
827 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
828 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
830 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
831 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
832 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[TMP0]], [[IV_NEXT]]
833 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
835 ; CHECK-NEXT: ret void
840 for.body: ; preds = %entry, %for.body
841 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
842 %iv.next = add i8 %iv, 1
843 %zext = zext i8 %iv.next to i16
844 %cmp = icmp slt i16 254, %zext
845 br i1 %cmp, label %for.body, label %for.end
847 for.end: ; preds = %for.body, %entry
851 define void @slt_non_constant_lhs(i16 %n) mustprogress {
852 ; CHECK-LABEL: @slt_non_constant_lhs(
854 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
856 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
857 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
858 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
859 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[N:%.*]], [[ZEXT]]
860 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
862 ; CHECK-NEXT: ret void
867 for.body: ; preds = %entry, %for.body
868 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
869 %iv.next = add i8 %iv, 1
870 %zext = zext i8 %iv.next to i16
871 %cmp = icmp slt i16 %n, %zext
872 br i1 %cmp, label %for.body, label %for.end
874 for.end: ; preds = %for.body, %entry
878 define void @ult_constant_lhs(i16 %n.raw, i8 %start) mustprogress {
879 ; CHECK-LABEL: @ult_constant_lhs(
881 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
882 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
884 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
885 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
886 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[TMP0]], [[IV_NEXT]]
887 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
889 ; CHECK-NEXT: ret void
894 for.body: ; preds = %entry, %for.body
895 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
896 %iv.next = add i8 %iv, 1
897 %zext = zext i8 %iv.next to i16
898 %cmp = icmp ult i16 254, %zext
899 br i1 %cmp, label %for.body, label %for.end
901 for.end: ; preds = %for.body, %entry
905 define void @ult_non_constant_lhs(i16 %n) mustprogress {
906 ; CHECK-LABEL: @ult_non_constant_lhs(
908 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
910 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
911 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
912 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
913 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[N:%.*]], [[ZEXT]]
914 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
916 ; CHECK-NEXT: ret void
921 for.body: ; preds = %entry, %for.body
922 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
923 %iv.next = add i8 %iv, 1
924 %zext = zext i8 %iv.next to i16
925 %cmp = icmp ult i16 %n, %zext
926 br i1 %cmp, label %for.body, label %for.end
928 for.end: ; preds = %for.body, %entry
932 define i16 @ult_multiuse_profit(i16 %n.raw, i8 %start) mustprogress {
933 ; CHECK-LABEL: @ult_multiuse_profit(
935 ; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[START:%.*]], 1
936 ; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i16
937 ; CHECK-NEXT: [[TMP2:%.*]] = trunc i16 254 to i8
938 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
940 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START]], [[ENTRY:%.*]] ]
941 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
942 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[TMP2]]
943 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
945 ; CHECK-NEXT: [[UMAX:%.*]] = call i16 @llvm.umax.i16(i16 [[TMP1]], i16 254)
946 ; CHECK-NEXT: ret i16 [[UMAX]]
951 for.body: ; preds = %entry, %for.body
952 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
953 %iv.next = add i8 %iv, 1
954 %zext = zext i8 %iv.next to i16
955 %cmp = icmp ult i16 %zext, 254
956 br i1 %cmp, label %for.body, label %for.end
958 for.end: ; preds = %for.body, %entry
962 define i16 @ult_multiuse_profit2(i16 %n.raw, i8 %start) mustprogress {
963 ; CHECK-LABEL: @ult_multiuse_profit2(
965 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 254 to i8
966 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
968 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
969 ; CHECK-NEXT: [[IV2:%.*]] = phi i16 [ [[ZEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY]] ]
970 ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
971 ; CHECK-NEXT: [[ZEXT]] = zext i8 [[IV_NEXT]] to i16
972 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[TMP0]]
973 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
975 ; CHECK-NEXT: [[IV2_LCSSA:%.*]] = phi i16 [ [[IV2]], [[FOR_BODY]] ]
976 ; CHECK-NEXT: ret i16 [[IV2_LCSSA]]
981 for.body: ; preds = %entry, %for.body
982 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
983 %iv2 = phi i16 [%zext, %for.body], [0, %entry]
984 %iv.next = add i8 %iv, 1
985 %zext = zext i8 %iv.next to i16
986 %cmp = icmp ult i16 %zext, 254
987 br i1 %cmp, label %for.body, label %for.end
989 for.end: ; preds = %for.body, %entry
993 define void @slt_restricted_rhs(i16 %n.raw) mustprogress {
994 ; CHECK-LABEL: @slt_restricted_rhs(
996 ; CHECK-NEXT: [[N:%.*]] = and i16 [[N_RAW:%.*]], 255
997 ; CHECK-NEXT: [[SMAX:%.*]] = call i16 @llvm.smax.i16(i16 [[N]], i16 1)
998 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
1000 ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i16 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
1001 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i16 [[INDVARS_IV]], 1
1002 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i16 [[INDVARS_IV_NEXT]], [[SMAX]]
1003 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
1005 ; CHECK-NEXT: ret void
1008 %n = and i16 %n.raw, 255
1011 for.body: ; preds = %entry, %for.body
1012 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
1013 %iv.next = add i8 %iv, 1
1014 %zext = zext i8 %iv.next to i16
1015 %cmp = icmp slt i16 %zext, %n
1016 br i1 %cmp, label %for.body, label %for.end
1018 for.end: ; preds = %for.body, %entry
1022 define void @slt_guarded_rhs(i16 %n) mustprogress {
1023 ; CHECK-LABEL: @slt_guarded_rhs(
1024 ; CHECK-NEXT: entry:
1025 ; CHECK-NEXT: [[IN_RANGE:%.*]] = icmp ult i16 [[N:%.*]], 256
1026 ; CHECK-NEXT: br i1 [[IN_RANGE]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
1027 ; CHECK: for.body.preheader:
1028 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 [[N]] to i8
1029 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
1031 ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_BODY_PREHEADER]] ]
1032 ; CHECK-NEXT: [[IV_NEXT]] = add nuw i8 [[IV]], 1
1033 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[TMP0]]
1034 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
1035 ; CHECK: for.end.loopexit:
1036 ; CHECK-NEXT: br label [[FOR_END]]
1038 ; CHECK-NEXT: ret void
1041 %in_range = icmp ult i16 %n, 256
1042 br i1 %in_range, label %for.body, label %for.end
1044 for.body: ; preds = %entry, %for.body
1045 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
1046 %iv.next = add i8 %iv, 1
1047 %zext = zext i8 %iv.next to i16
1048 %cmp = icmp slt i16 %zext, %n
1049 br i1 %cmp, label %for.body, label %for.end
1051 for.end: ; preds = %for.body, %entry