1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -indvars -S < %s | FileCheck %s
3
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.
7
8target 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"
9
10define void @slt_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
11; CHECK-LABEL: @slt_constant_rhs(
12; CHECK-NEXT:  entry:
13; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
14; CHECK:       for.body:
15; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
16; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
17; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
18; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i16 [[ZEXT]], 254
19; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
20; CHECK:       for.end:
21; CHECK-NEXT:    ret void
22;
23entry:
24  br label %for.body
25
26for.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
32
33for.end:                                          ; preds = %for.body, %entry
34  ret void
35}
36
37;; Range logic doesn't depend on must execute
38define 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:    br label [[FOR_BODY:%.*]]
42; CHECK:       for.body:
43; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
44; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
45; CHECK-NEXT:    call void @unknown()
46; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
47; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i16 [[ZEXT]], 254
48; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
49; CHECK:       for.end:
50; CHECK-NEXT:    ret void
51;
52entry:
53  br label %for.body
54
55for.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
62
63for.end:                                          ; preds = %for.body, %entry
64  ret void
65}
66
67;; Range logic doesn't depend on must execute
68define 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:    br label [[FOR_BODY:%.*]]
72; CHECK:       for.body:
73; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
74; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
75; CHECK-NEXT:    br i1 [[C:%.*]], label [[LATCH]], label [[FOR_END:%.*]]
76; CHECK:       latch:
77; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
78; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i16 [[ZEXT]], 254
79; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]]
80; CHECK:       for.end:
81; CHECK-NEXT:    ret void
82;
83entry:
84  br label %for.body
85
86for.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
90
91latch:
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
95
96for.end:                                          ; preds = %for.body, %entry
97  ret void
98}
99
100define 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
112;
113entry:
114  br label %for.body
115
116for.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
122
123for.end:                                          ; preds = %for.body, %entry
124  ret void
125}
126
127; Case where we could prove this using range facts, but not must exit reasoning
128define 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:    br label [[FOR_BODY:%.*]]
133; CHECK:       for.body:
134; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
135; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
136; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
137; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i16 [[ZEXT]], [[N]]
138; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
139; CHECK:       for.end:
140; CHECK-NEXT:    ret void
141;
142entry:
143  %n = and i16 %n.raw, 255
144  br label %for.body
145
146for.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
152
153for.end:                                          ; preds = %for.body, %entry
154  ret void
155}
156
157@G = external global i8
158
159; Negative case where the loop could be infinite and make progress
160define void @slt_neg_well_defined_infinite(i16 %n) mustprogress {
161; CHECK-LABEL: @slt_neg_well_defined_infinite(
162; CHECK-NEXT:  entry:
163; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
164; CHECK:       for.body:
165; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
166; CHECK-NEXT:    store volatile i8 [[IV]], i8* @G, align 1
167; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
168; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
169; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]]
170; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
171; CHECK:       for.end:
172; CHECK-NEXT:    ret void
173;
174entry:
175  br label %for.body
176
177for.body:                                         ; preds = %entry, %for.body
178  %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
179  store volatile i8 %iv, i8* @G
180  %iv.next = add i8 %iv, 1
181  %zext = zext i8 %iv.next to i16
182  %cmp = icmp slt i16 %zext, %n
183  br i1 %cmp, label %for.body, label %for.end
184
185for.end:                                          ; preds = %for.body, %entry
186  ret void
187}
188
189; Negative case with no mustprogress rsltuirement
190define void @slt_neg_no_mustprogress(i16 %n) {
191; CHECK-LABEL: @slt_neg_no_mustprogress(
192; CHECK-NEXT:  entry:
193; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
194; CHECK:       for.body:
195; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
196; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
197; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
198; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]]
199; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
200; CHECK:       for.end:
201; CHECK-NEXT:    ret void
202;
203entry:
204  br label %for.body
205
206for.body:                                         ; preds = %entry, %for.body
207  %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
208  %iv.next = add i8 %iv, 1
209  %zext = zext i8 %iv.next to i16
210  %cmp = icmp slt i16 %zext, %n
211  br i1 %cmp, label %for.body, label %for.end
212
213for.end:                                          ; preds = %for.body, %entry
214  ret void
215}
216
217declare void @unknown()
218
219define void @slt_neg_abnormal_exit(i16 %n) mustprogress {
220; CHECK-LABEL: @slt_neg_abnormal_exit(
221; CHECK-NEXT:  entry:
222; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
223; CHECK:       for.body:
224; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
225; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
226; CHECK-NEXT:    call void @unknown()
227; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
228; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]]
229; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
230; CHECK:       for.end:
231; CHECK-NEXT:    ret void
232;
233entry:
234  br label %for.body
235
236for.body:                                         ; preds = %entry, %for.body
237  %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
238  %iv.next = add i8 %iv, 1
239  call void @unknown()
240  %zext = zext i8 %iv.next to i16
241  %cmp = icmp slt i16 %zext, %n
242  br i1 %cmp, label %for.body, label %for.end
243
244for.end:                                          ; preds = %for.body, %entry
245  ret void
246}
247
248; For the other comparison flavors, we only bother to repeat the positive
249; tests since the negative variants are mostly the same.
250
251define void @ne_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
252; CHECK-LABEL: @ne_constant_rhs(
253; CHECK-NEXT:  entry:
254; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
255; CHECK:       for.body:
256; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
257; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
258; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
259; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i16 [[ZEXT]], 254
260; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
261; CHECK:       for.end:
262; CHECK-NEXT:    ret void
263;
264entry:
265  br label %for.body
266
267for.body:                                         ; preds = %entry, %for.body
268  %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
269  %iv.next = add i8 %iv, 1
270  %zext = zext i8 %iv.next to i16
271  %cmp = icmp ne i16 %zext, 254
272  br i1 %cmp, label %for.body, label %for.end
273
274for.end:                                          ; preds = %for.body, %entry
275  ret void
276}
277
278define void @ne_non_constant_rhs(i16 %n) mustprogress {
279; CHECK-LABEL: @ne_non_constant_rhs(
280; CHECK-NEXT:  entry:
281; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
282; CHECK:       for.body:
283; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
284; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
285; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
286; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i16 [[ZEXT]], [[N:%.*]]
287; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
288; CHECK:       for.end:
289; CHECK-NEXT:    ret void
290;
291entry:
292  br label %for.body
293
294for.body:                                         ; preds = %entry, %for.body
295  %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
296  %iv.next = add i8 %iv, 1
297  %zext = zext i8 %iv.next to i16
298  %cmp = icmp ne i16 %zext, %n
299  br i1 %cmp, label %for.body, label %for.end
300
301for.end:                                          ; preds = %for.body, %entry
302  ret void
303}
304
305define void @eq_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
306; CHECK-LABEL: @eq_constant_rhs(
307; CHECK-NEXT:  entry:
308; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
309; CHECK:       for.body:
310; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
311; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
312; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
313; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[ZEXT]], 254
314; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
315; CHECK:       for.end:
316; CHECK-NEXT:    ret void
317;
318entry:
319  br label %for.body
320
321for.body:                                         ; preds = %entry, %for.body
322  %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
323  %iv.next = add i8 %iv, 1
324  %zext = zext i8 %iv.next to i16
325  %cmp = icmp eq i16 %zext, 254
326  br i1 %cmp, label %for.body, label %for.end
327
328for.end:                                          ; preds = %for.body, %entry
329  ret void
330}
331
332define void @eq_non_constant_rhs(i16 %n) mustprogress {
333; CHECK-LABEL: @eq_non_constant_rhs(
334; CHECK-NEXT:  entry:
335; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
336; CHECK:       for.body:
337; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
338; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
339; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
340; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[ZEXT]], [[N:%.*]]
341; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
342; CHECK:       for.end:
343; CHECK-NEXT:    ret void
344;
345entry:
346  br label %for.body
347
348for.body:                                         ; preds = %entry, %for.body
349  %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
350  %iv.next = add i8 %iv, 1
351  %zext = zext i8 %iv.next to i16
352  %cmp = icmp eq i16 %zext, %n
353  br i1 %cmp, label %for.body, label %for.end
354
355for.end:                                          ; preds = %for.body, %entry
356  ret void
357}
358
359define void @sgt_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
360; CHECK-LABEL: @sgt_constant_rhs(
361; CHECK-NEXT:  entry:
362; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
363; CHECK:       for.body:
364; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
365; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
366; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
367; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i16 [[ZEXT]], 254
368; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
369; CHECK:       for.end:
370; CHECK-NEXT:    ret void
371;
372entry:
373  br label %for.body
374
375for.body:                                         ; preds = %entry, %for.body
376  %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
377  %iv.next = add i8 %iv, 1
378  %zext = zext i8 %iv.next to i16
379  %cmp = icmp sgt i16 %zext, 254
380  br i1 %cmp, label %for.body, label %for.end
381
382for.end:                                          ; preds = %for.body, %entry
383  ret void
384}
385
386define void @sgt_non_constant_rhs(i16 %n) mustprogress {
387; CHECK-LABEL: @sgt_non_constant_rhs(
388; CHECK-NEXT:  entry:
389; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
390; CHECK:       for.body:
391; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
392; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
393; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
394; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i16 [[ZEXT]], [[N:%.*]]
395; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
396; CHECK:       for.end:
397; CHECK-NEXT:    ret void
398;
399entry:
400  br label %for.body
401
402for.body:                                         ; preds = %entry, %for.body
403  %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
404  %iv.next = add i8 %iv, 1
405  %zext = zext i8 %iv.next to i16
406  %cmp = icmp sgt i16 %zext, %n
407  br i1 %cmp, label %for.body, label %for.end
408
409for.end:                                          ; preds = %for.body, %entry
410  ret void
411}
412
413define void @sle_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
414; CHECK-LABEL: @sle_constant_rhs(
415; CHECK-NEXT:  entry:
416; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
417; CHECK:       for.body:
418; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
419; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
420; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
421; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i16 [[ZEXT]], 254
422; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
423; CHECK:       for.end:
424; CHECK-NEXT:    ret void
425;
426entry:
427  br label %for.body
428
429for.body:                                         ; preds = %entry, %for.body
430  %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
431  %iv.next = add i8 %iv, 1
432  %zext = zext i8 %iv.next to i16
433  %cmp = icmp sle i16 %zext, 254
434  br i1 %cmp, label %for.body, label %for.end
435
436for.end:                                          ; preds = %for.body, %entry
437  ret void
438}
439
440define void @sle_non_constant_rhs(i16 %n) mustprogress {
441; CHECK-LABEL: @sle_non_constant_rhs(
442; CHECK-NEXT:  entry:
443; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
444; CHECK:       for.body:
445; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
446; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
447; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
448; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i16 [[ZEXT]], [[N:%.*]]
449; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
450; CHECK:       for.end:
451; CHECK-NEXT:    ret void
452;
453entry:
454  br label %for.body
455
456for.body:                                         ; preds = %entry, %for.body
457  %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
458  %iv.next = add i8 %iv, 1
459  %zext = zext i8 %iv.next to i16
460  %cmp = icmp sle i16 %zext, %n
461  br i1 %cmp, label %for.body, label %for.end
462
463for.end:                                          ; preds = %for.body, %entry
464  ret void
465}
466
467define void @sge_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
468; CHECK-LABEL: @sge_constant_rhs(
469; CHECK-NEXT:  entry:
470; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
471; CHECK:       for.body:
472; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
473; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
474; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
475; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i16 [[ZEXT]], 254
476; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
477; CHECK:       for.end:
478; CHECK-NEXT:    ret void
479;
480entry:
481  br label %for.body
482
483for.body:                                         ; preds = %entry, %for.body
484  %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
485  %iv.next = add i8 %iv, 1
486  %zext = zext i8 %iv.next to i16
487  %cmp = icmp sge i16 %zext, 254
488  br i1 %cmp, label %for.body, label %for.end
489
490for.end:                                          ; preds = %for.body, %entry
491  ret void
492}
493
494define void @sge_non_constant_rhs(i16 %n) mustprogress {
495; CHECK-LABEL: @sge_non_constant_rhs(
496; CHECK-NEXT:  entry:
497; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
498; CHECK:       for.body:
499; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
500; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
501; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
502; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i16 [[ZEXT]], [[N:%.*]]
503; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
504; CHECK:       for.end:
505; CHECK-NEXT:    ret void
506;
507entry:
508  br label %for.body
509
510for.body:                                         ; preds = %entry, %for.body
511  %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
512  %iv.next = add i8 %iv, 1
513  %zext = zext i8 %iv.next to i16
514  %cmp = icmp sge i16 %zext, %n
515  br i1 %cmp, label %for.body, label %for.end
516
517for.end:                                          ; preds = %for.body, %entry
518  ret void
519}
520
521define void @ult_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
522; CHECK-LABEL: @ult_constant_rhs(
523; CHECK-NEXT:  entry:
524; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
525; CHECK:       for.body:
526; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
527; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
528; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
529; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i16 [[ZEXT]], 254
530; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
531; CHECK:       for.end:
532; CHECK-NEXT:    ret void
533;
534entry:
535  br label %for.body
536
537for.body:                                         ; preds = %entry, %for.body
538  %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
539  %iv.next = add i8 %iv, 1
540  %zext = zext i8 %iv.next to i16
541  %cmp = icmp ult i16 %zext, 254
542  br i1 %cmp, label %for.body, label %for.end
543
544for.end:                                          ; preds = %for.body, %entry
545  ret void
546}
547
548define void @ult_non_constant_rhs(i16 %n) mustprogress {
549; CHECK-LABEL: @ult_non_constant_rhs(
550; CHECK-NEXT:  entry:
551; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
552; CHECK:       for.body:
553; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
554; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
555; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
556; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i16 [[ZEXT]], [[N:%.*]]
557; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
558; CHECK:       for.end:
559; CHECK-NEXT:    ret void
560;
561entry:
562  br label %for.body
563
564for.body:                                         ; preds = %entry, %for.body
565  %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
566  %iv.next = add i8 %iv, 1
567  %zext = zext i8 %iv.next to i16
568  %cmp = icmp ult i16 %zext, %n
569  br i1 %cmp, label %for.body, label %for.end
570
571for.end:                                          ; preds = %for.body, %entry
572  ret void
573}
574
575define void @ugt_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
576; CHECK-LABEL: @ugt_constant_rhs(
577; CHECK-NEXT:  entry:
578; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
579; CHECK:       for.body:
580; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
581; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
582; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
583; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i16 [[ZEXT]], 254
584; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
585; CHECK:       for.end:
586; CHECK-NEXT:    ret void
587;
588entry:
589  br label %for.body
590
591for.body:                                         ; preds = %entry, %for.body
592  %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
593  %iv.next = add i8 %iv, 1
594  %zext = zext i8 %iv.next to i16
595  %cmp = icmp ugt i16 %zext, 254
596  br i1 %cmp, label %for.body, label %for.end
597
598for.end:                                          ; preds = %for.body, %entry
599  ret void
600}
601
602define void @ugt_non_constant_rhs(i16 %n) mustprogress {
603; CHECK-LABEL: @ugt_non_constant_rhs(
604; CHECK-NEXT:  entry:
605; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
606; CHECK:       for.body:
607; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
608; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
609; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
610; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i16 [[ZEXT]], [[N:%.*]]
611; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
612; CHECK:       for.end:
613; CHECK-NEXT:    ret void
614;
615entry:
616  br label %for.body
617
618for.body:                                         ; preds = %entry, %for.body
619  %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
620  %iv.next = add i8 %iv, 1
621  %zext = zext i8 %iv.next to i16
622  %cmp = icmp ugt i16 %zext, %n
623  br i1 %cmp, label %for.body, label %for.end
624
625for.end:                                          ; preds = %for.body, %entry
626  ret void
627}
628
629define void @ule_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
630; CHECK-LABEL: @ule_constant_rhs(
631; CHECK-NEXT:  entry:
632; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
633; CHECK:       for.body:
634; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
635; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
636; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
637; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i16 [[ZEXT]], 254
638; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
639; CHECK:       for.end:
640; CHECK-NEXT:    ret void
641;
642entry:
643  br label %for.body
644
645for.body:                                         ; preds = %entry, %for.body
646  %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
647  %iv.next = add i8 %iv, 1
648  %zext = zext i8 %iv.next to i16
649  %cmp = icmp ule i16 %zext, 254
650  br i1 %cmp, label %for.body, label %for.end
651
652for.end:                                          ; preds = %for.body, %entry
653  ret void
654}
655
656define void @ule_non_constant_rhs(i16 %n) mustprogress {
657; CHECK-LABEL: @ule_non_constant_rhs(
658; CHECK-NEXT:  entry:
659; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
660; CHECK:       for.body:
661; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
662; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
663; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
664; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i16 [[ZEXT]], [[N:%.*]]
665; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
666; CHECK:       for.end:
667; CHECK-NEXT:    ret void
668;
669entry:
670  br label %for.body
671
672for.body:                                         ; preds = %entry, %for.body
673  %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
674  %iv.next = add i8 %iv, 1
675  %zext = zext i8 %iv.next to i16
676  %cmp = icmp ule i16 %zext, %n
677  br i1 %cmp, label %for.body, label %for.end
678
679for.end:                                          ; preds = %for.body, %entry
680  ret void
681}
682
683define void @uge_constant_rhs(i16 %n.raw, i8 %start) mustprogress {
684; CHECK-LABEL: @uge_constant_rhs(
685; CHECK-NEXT:  entry:
686; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
687; CHECK:       for.body:
688; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
689; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
690; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
691; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i16 [[ZEXT]], 254
692; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
693; CHECK:       for.end:
694; CHECK-NEXT:    ret void
695;
696entry:
697  br label %for.body
698
699for.body:                                         ; preds = %entry, %for.body
700  %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ]
701  %iv.next = add i8 %iv, 1
702  %zext = zext i8 %iv.next to i16
703  %cmp = icmp uge i16 %zext, 254
704  br i1 %cmp, label %for.body, label %for.end
705
706for.end:                                          ; preds = %for.body, %entry
707  ret void
708}
709
710define void @uge_non_constant_rhs(i16 %n) mustprogress {
711; CHECK-LABEL: @uge_non_constant_rhs(
712; CHECK-NEXT:  entry:
713; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
714; CHECK:       for.body:
715; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
716; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
717; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16
718; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i16 [[ZEXT]], [[N:%.*]]
719; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
720; CHECK:       for.end:
721; CHECK-NEXT:    ret void
722;
723entry:
724  br label %for.body
725
726for.body:                                         ; preds = %entry, %for.body
727  %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
728  %iv.next = add i8 %iv, 1
729  %zext = zext i8 %iv.next to i16
730  %cmp = icmp uge i16 %zext, %n
731  br i1 %cmp, label %for.body, label %for.end
732
733for.end:                                          ; preds = %for.body, %entry
734  ret void
735}
736