Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / IndVarSimplify / finite-exit-comparisons.ll
blob038129e9a7cf2145e7015bb861e3459e69e29a7c
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(
12 ; CHECK-NEXT:  entry:
13 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
14 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
15 ; CHECK:       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:%.*]]
20 ; CHECK:       for.end:
21 ; CHECK-NEXT:    ret void
23 entry:
24   br label %for.body
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
34   ret void
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(
40 ; CHECK-NEXT:  entry:
41 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
42 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
43 ; CHECK:       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:%.*]]
49 ; CHECK:       for.end:
50 ; CHECK-NEXT:    ret void
52 entry:
53   br label %for.body
55 for.body:                                         ; preds = %entry, %for.body
56   %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
57   %iv.next = add i8 %iv, 1
58   call void @unknown()
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
64   ret void
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(
70 ; CHECK-NEXT:  entry:
71 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
72 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
73 ; CHECK:       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:%.*]]
77 ; CHECK:       latch:
78 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[TMP0]]
79 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]]
80 ; CHECK:       for.end:
81 ; CHECK-NEXT:    ret void
83 entry:
84   br label %for.body
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
91 latch:
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
97   ret void
100 define void @slt_non_constant_rhs(i16 %n) mustprogress {
101 ; CHECK-LABEL: @slt_non_constant_rhs(
102 ; CHECK-NEXT:  entry:
103 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
104 ; CHECK:       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:%.*]]
110 ; CHECK:       for.end:
111 ; CHECK-NEXT:    ret void
113 entry:
114   br label %for.body
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
124   ret void
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(
130 ; CHECK-NEXT:  entry:
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:%.*]]
134 ; CHECK:       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:%.*]]
139 ; CHECK:       for.end:
140 ; CHECK-NEXT:    ret void
142 entry:
143   %n = and i16 %n.raw, 255
144   br label %for.body
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
154   ret void
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(
162 ; CHECK-NEXT:  entry:
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:%.*]]
168 ; CHECK:       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]]
172 ; CHECK:       for.end:
173 ; CHECK-NEXT:    ret void
175 entry:
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
184   ret void
187 define void @slt_neg_multiple_use2(i8 %start, i16 %n) mustprogress {
188 ; CHECK-LABEL: @slt_neg_multiple_use2(
189 ; CHECK-NEXT:  entry:
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:%.*]]
195 ; CHECK:       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]]
199 ; CHECK:       for.end:
200 ; CHECK-NEXT:    ret void
202 entry:
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
211   ret void
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(
219 ; CHECK-NEXT:  entry:
220 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
221 ; CHECK:       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:%.*]]
228 ; CHECK:       for.end:
229 ; CHECK-NEXT:    ret void
231 entry:
232   br label %for.body
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
243   ret void
246 ; Negative case with no mustprogress rsltuirement
247 define void @slt_neg_no_mustprogress(i16 %n) {
248 ; CHECK-LABEL: @slt_neg_no_mustprogress(
249 ; CHECK-NEXT:  entry:
250 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
251 ; CHECK:       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:%.*]]
257 ; CHECK:       for.end:
258 ; CHECK-NEXT:    ret void
260 entry:
261   br label %for.body
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
271   ret void
274 declare void @unknown()
276 define void @slt_neg_abnormal_exit(i16 %n) mustprogress {
277 ; CHECK-LABEL: @slt_neg_abnormal_exit(
278 ; CHECK-NEXT:  entry:
279 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
280 ; CHECK:       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:%.*]]
287 ; CHECK:       for.end:
288 ; CHECK-NEXT:    ret void
290 entry:
291   br label %for.body
293 for.body:                                         ; preds = %entry, %for.body
294   %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
295   %iv.next = add i8 %iv, 1
296   call void @unknown()
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
302   ret void
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(
310 ; CHECK-NEXT:  entry:
311 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
312 ; CHECK:       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:%.*]]
318 ; CHECK:       for.end:
319 ; CHECK-NEXT:    ret void
321 entry:
322   br label %for.body
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
332   ret void
335 define void @ne_non_constant_rhs(i16 %n) mustprogress {
336 ; CHECK-LABEL: @ne_non_constant_rhs(
337 ; CHECK-NEXT:  entry:
338 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
339 ; CHECK:       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:%.*]]
345 ; CHECK:       for.end:
346 ; CHECK-NEXT:    ret void
348 entry:
349   br label %for.body
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
359   ret void
362 define void @eq_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
363 ; CHECK-LABEL: @eq_constant_rhs(
364 ; CHECK-NEXT:  entry:
365 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
366 ; CHECK:       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:%.*]]
372 ; CHECK:       for.end:
373 ; CHECK-NEXT:    ret void
375 entry:
376   br label %for.body
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
386   ret void
389 define void @eq_non_constant_rhs(i16 %n) mustprogress {
390 ; CHECK-LABEL: @eq_non_constant_rhs(
391 ; CHECK-NEXT:  entry:
392 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
393 ; CHECK:       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:%.*]]
399 ; CHECK:       for.end:
400 ; CHECK-NEXT:    ret void
402 entry:
403   br label %for.body
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
413   ret void
416 define void @sgt_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
417 ; CHECK-LABEL: @sgt_constant_rhs(
418 ; CHECK-NEXT:  entry:
419 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
420 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
421 ; CHECK:       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:%.*]]
426 ; CHECK:       for.end:
427 ; CHECK-NEXT:    ret void
429 entry:
430   br label %for.body
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
440   ret void
443 define void @sgt_non_constant_rhs(i16 %n) mustprogress {
444 ; CHECK-LABEL: @sgt_non_constant_rhs(
445 ; CHECK-NEXT:  entry:
446 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
447 ; CHECK:       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:%.*]]
453 ; CHECK:       for.end:
454 ; CHECK-NEXT:    ret void
456 entry:
457   br label %for.body
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
467   ret void
470 define void @sle_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
471 ; CHECK-LABEL: @sle_constant_rhs(
472 ; CHECK-NEXT:  entry:
473 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
474 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
475 ; CHECK:       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:%.*]]
480 ; CHECK:       for.end:
481 ; CHECK-NEXT:    ret void
483 entry:
484   br label %for.body
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
494   ret void
497 define void @sle_non_constant_rhs(i16 %n) mustprogress {
498 ; CHECK-LABEL: @sle_non_constant_rhs(
499 ; CHECK-NEXT:  entry:
500 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
501 ; CHECK:       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:%.*]]
507 ; CHECK:       for.end:
508 ; CHECK-NEXT:    ret void
510 entry:
511   br label %for.body
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
521   ret void
524 define void @sge_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
525 ; CHECK-LABEL: @sge_constant_rhs(
526 ; CHECK-NEXT:  entry:
527 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
528 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
529 ; CHECK:       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:%.*]]
534 ; CHECK:       for.end:
535 ; CHECK-NEXT:    ret void
537 entry:
538   br label %for.body
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
548   ret void
551 define void @sge_non_constant_rhs(i16 %n) mustprogress {
552 ; CHECK-LABEL: @sge_non_constant_rhs(
553 ; CHECK-NEXT:  entry:
554 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
555 ; CHECK:       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:%.*]]
561 ; CHECK:       for.end:
562 ; CHECK-NEXT:    ret void
564 entry:
565   br label %for.body
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
575   ret void
578 define void @ult_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
579 ; CHECK-LABEL: @ult_constant_rhs(
580 ; CHECK-NEXT:  entry:
581 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
582 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
583 ; CHECK:       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:%.*]]
588 ; CHECK:       for.end:
589 ; CHECK-NEXT:    ret void
591 entry:
592   br label %for.body
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
602   ret void
605 define void @ult_non_constant_rhs(i16 %n) mustprogress {
606 ; CHECK-LABEL: @ult_non_constant_rhs(
607 ; CHECK-NEXT:  entry:
608 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
609 ; CHECK:       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:%.*]]
615 ; CHECK:       for.end:
616 ; CHECK-NEXT:    ret void
618 entry:
619   br label %for.body
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
629   ret void
632 define void @ugt_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
633 ; CHECK-LABEL: @ugt_constant_rhs(
634 ; CHECK-NEXT:  entry:
635 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
636 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
637 ; CHECK:       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:%.*]]
642 ; CHECK:       for.end:
643 ; CHECK-NEXT:    ret void
645 entry:
646   br label %for.body
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
656   ret void
659 define void @ugt_neg_non_loop(i16 %n.raw, i8 %start) mustprogress {
660 ; CHECK-LABEL: @ugt_neg_non_loop(
661 ; CHECK-NEXT:  entry:
662 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
663 ; CHECK:       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:%.*]]
669 ; CHECK:       for.end:
670 ; CHECK-NEXT:    ret void
672 entry:
673   br label %for.body
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
683   ret void
686 define void @ugt_non_constant_rhs(i16 %n) mustprogress {
687 ; CHECK-LABEL: @ugt_non_constant_rhs(
688 ; CHECK-NEXT:  entry:
689 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
690 ; CHECK:       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:%.*]]
696 ; CHECK:       for.end:
697 ; CHECK-NEXT:    ret void
699 entry:
700   br label %for.body
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
710   ret void
713 define void @ule_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
714 ; CHECK-LABEL: @ule_constant_rhs(
715 ; CHECK-NEXT:  entry:
716 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
717 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
718 ; CHECK:       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:%.*]]
723 ; CHECK:       for.end:
724 ; CHECK-NEXT:    ret void
726 entry:
727   br label %for.body
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
737   ret void
740 define void @ule_non_constant_rhs(i16 %n) mustprogress {
741 ; CHECK-LABEL: @ule_non_constant_rhs(
742 ; CHECK-NEXT:  entry:
743 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
744 ; CHECK:       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:%.*]]
750 ; CHECK:       for.end:
751 ; CHECK-NEXT:    ret void
753 entry:
754   br label %for.body
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
764   ret void
767 define void @uge_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
768 ; CHECK-LABEL: @uge_constant_rhs(
769 ; CHECK-NEXT:  entry:
770 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
771 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
772 ; CHECK:       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:%.*]]
777 ; CHECK:       for.end:
778 ; CHECK-NEXT:    ret void
780 entry:
781   br label %for.body
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
791   ret void
794 define void @uge_non_constant_rhs(i16 %n) mustprogress {
795 ; CHECK-LABEL: @uge_non_constant_rhs(
796 ; CHECK-NEXT:  entry:
797 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
798 ; CHECK:       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:%.*]]
804 ; CHECK:       for.end:
805 ; CHECK-NEXT:    ret void
807 entry:
808   br label %for.body
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
818   ret void
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(
826 ; CHECK-NEXT:  entry:
827 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
828 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
829 ; CHECK:       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:%.*]]
834 ; CHECK:       for.end:
835 ; CHECK-NEXT:    ret void
837 entry:
838   br label %for.body
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
848   ret void
851 define void @slt_non_constant_lhs(i16 %n) mustprogress {
852 ; CHECK-LABEL: @slt_non_constant_lhs(
853 ; CHECK-NEXT:  entry:
854 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
855 ; CHECK:       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:%.*]]
861 ; CHECK:       for.end:
862 ; CHECK-NEXT:    ret void
864 entry:
865   br label %for.body
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
875   ret void
878 define void @ult_constant_lhs(i16 %n.raw, i8 %start) mustprogress {
879 ; CHECK-LABEL: @ult_constant_lhs(
880 ; CHECK-NEXT:  entry:
881 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
882 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
883 ; CHECK:       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:%.*]]
888 ; CHECK:       for.end:
889 ; CHECK-NEXT:    ret void
891 entry:
892   br label %for.body
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
902   ret void
905 define void @ult_non_constant_lhs(i16 %n) mustprogress {
906 ; CHECK-LABEL: @ult_non_constant_lhs(
907 ; CHECK-NEXT:  entry:
908 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
909 ; CHECK:       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:%.*]]
915 ; CHECK:       for.end:
916 ; CHECK-NEXT:    ret void
918 entry:
919   br label %for.body
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
929   ret void
932 define i16 @ult_multiuse_profit(i16 %n.raw, i8 %start) mustprogress {
933 ; CHECK-LABEL: @ult_multiuse_profit(
934 ; CHECK-NEXT:  entry:
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:%.*]]
939 ; CHECK:       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:%.*]]
944 ; CHECK:       for.end:
945 ; CHECK-NEXT:    [[UMAX:%.*]] = call i16 @llvm.umax.i16(i16 [[TMP1]], i16 254)
946 ; CHECK-NEXT:    ret i16 [[UMAX]]
948 entry:
949   br label %for.body
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
959   ret i16 %zext
962 define i16 @ult_multiuse_profit2(i16 %n.raw, i8 %start) mustprogress {
963 ; CHECK-LABEL: @ult_multiuse_profit2(
964 ; CHECK-NEXT:  entry:
965 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i16 254 to i8
966 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
967 ; CHECK:       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:%.*]]
974 ; CHECK:       for.end:
975 ; CHECK-NEXT:    [[IV2_LCSSA:%.*]] = phi i16 [ [[IV2]], [[FOR_BODY]] ]
976 ; CHECK-NEXT:    ret i16 [[IV2_LCSSA]]
978 entry:
979   br label %for.body
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
990   ret i16 %iv2
993 define void @slt_restricted_rhs(i16 %n.raw) mustprogress {
994 ; CHECK-LABEL: @slt_restricted_rhs(
995 ; CHECK-NEXT:  entry:
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:%.*]]
999 ; CHECK:       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:%.*]]
1004 ; CHECK:       for.end:
1005 ; CHECK-NEXT:    ret void
1007 entry:
1008   %n = and i16 %n.raw, 255
1009   br label %for.body
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
1019   ret void
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:%.*]]
1030 ; CHECK:       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]]
1037 ; CHECK:       for.end:
1038 ; CHECK-NEXT:    ret void
1040 entry:
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
1052   ret void