• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -correlated-propagation -S | FileCheck %s
3; PR2581
4
5define i32 @test1(i1 %C) {
6; CHECK-LABEL: @test1(
7; CHECK-NEXT:    br i1 [[C:%.*]], label [[EXIT:%.*]], label [[BODY:%.*]]
8; CHECK:       body:
9; CHECK-NEXT:    ret i32 11
10; CHECK:       exit:
11; CHECK-NEXT:    ret i32 10
12;
13  br i1 %C, label %exit, label %body
14
15body:           ; preds = %0
16  %A = select i1 %C, i32 10, i32 11
17  ret i32 %A
18
19exit:           ; preds = %0
20  ret i32 10
21}
22
23; PR4420
24declare i1 @ext()
25define i1 @test2() {
26; CHECK-LABEL: @test2(
27; CHECK-NEXT:  entry:
28; CHECK-NEXT:    [[COND:%.*]] = tail call i1 @ext()
29; CHECK-NEXT:    br i1 [[COND]], label [[BB1:%.*]], label [[BB2:%.*]]
30; CHECK:       bb1:
31; CHECK-NEXT:    [[COND2:%.*]] = tail call i1 @ext()
32; CHECK-NEXT:    br i1 [[COND2]], label [[BB3:%.*]], label [[BB2]]
33; CHECK:       bb2:
34; CHECK-NEXT:    ret i1 false
35; CHECK:       bb3:
36; CHECK-NEXT:    [[RES:%.*]] = tail call i1 @ext()
37; CHECK-NEXT:    ret i1 [[RES]]
38;
39entry:
40  %cond = tail call i1 @ext()
41  br i1 %cond, label %bb1, label %bb2
42
43bb1:
44  %cond2 = tail call i1 @ext()
45  br i1 %cond2, label %bb3, label %bb2
46
47bb2:
48  %cond_merge = phi i1 [ %cond, %entry ], [ false, %bb1 ]
49  ret i1 %cond_merge
50
51bb3:
52  %res = tail call i1 @ext()
53  ret i1 %res
54}
55
56; PR4855
57@gv = internal constant i8 7
58define i8 @test3(i8* %a) nounwind {
59; CHECK-LABEL: @test3(
60; CHECK-NEXT:  entry:
61; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8* [[A:%.*]], @gv
62; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB:%.*]]
63; CHECK:       bb:
64; CHECK-NEXT:    ret i8 0
65; CHECK:       bb2:
66; CHECK-NEXT:    [[SHOULD_BE_CONST:%.*]] = load i8, i8* @gv, align 1
67; CHECK-NEXT:    ret i8 [[SHOULD_BE_CONST]]
68;
69entry:
70  %cond = icmp eq i8* %a, @gv
71  br i1 %cond, label %bb2, label %bb
72
73bb:
74  ret i8 0
75
76bb2:
77  %should_be_const = load i8, i8* %a
78  ret i8 %should_be_const
79}
80
81; PR1757
82define i32 @test4(i32) {
83; CHECK-LABEL: @test4(
84; CHECK-NEXT:  EntryBlock:
85; CHECK-NEXT:    [[DOTDEMORGAN:%.*]] = icmp sgt i32 [[TMP0:%.*]], 2
86; CHECK-NEXT:    br i1 [[DOTDEMORGAN]], label [[GREATERTHANTWO:%.*]], label [[LESSTHANOREQUALTOTWO:%.*]]
87; CHECK:       GreaterThanTwo:
88; CHECK-NEXT:    br i1 false, label [[IMPOSSIBLE:%.*]], label [[NOTTWOANDGREATERTHANTWO:%.*]]
89; CHECK:       NotTwoAndGreaterThanTwo:
90; CHECK-NEXT:    ret i32 2
91; CHECK:       Impossible:
92; CHECK-NEXT:    ret i32 1
93; CHECK:       LessThanOrEqualToTwo:
94; CHECK-NEXT:    ret i32 0
95;
96EntryBlock:
97  %.demorgan = icmp sgt i32 %0, 2
98  br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo
99
100GreaterThanTwo:
101  icmp eq i32 %0, 2
102  br i1 %1, label %Impossible, label %NotTwoAndGreaterThanTwo
103
104NotTwoAndGreaterThanTwo:
105  ret i32 2
106
107Impossible:
108  ret i32 1
109
110LessThanOrEqualToTwo:
111  ret i32 0
112}
113
114declare i32* @f(i32*)
115define void @test5(i32* %x, i32* %y) {
116; CHECK-LABEL: @test5(
117; CHECK-NEXT:  entry:
118; CHECK-NEXT:    [[PRE:%.*]] = icmp eq i32* [[X:%.*]], null
119; CHECK-NEXT:    br i1 [[PRE]], label [[RETURN:%.*]], label [[LOOP:%.*]]
120; CHECK:       loop:
121; CHECK-NEXT:    [[PHI:%.*]] = phi i32* [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]
122; CHECK-NEXT:    [[F]] = tail call i32* @f(i32* [[PHI]])
123; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32* [[F]], [[Y:%.*]]
124; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], i32* [[F]], i32* null
125; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32* [[SEL]], null
126; CHECK-NEXT:    br i1 [[CMP2]], label [[RETURN]], label [[LOOP]]
127; CHECK:       return:
128; CHECK-NEXT:    ret void
129;
130entry:
131  %pre = icmp eq i32* %x, null
132  br i1 %pre, label %return, label %loop
133
134loop:
135  %phi = phi i32* [ %sel, %loop ], [ %x, %entry ]
136  %f = tail call i32* @f(i32* %phi)
137  %cmp1 = icmp ne i32* %f, %y
138  %sel = select i1 %cmp1, i32* %f, i32* null
139  %cmp2 = icmp eq i32* %sel, null
140  br i1 %cmp2, label %return, label %loop
141
142return:
143  ret void
144}
145
146define i32 @switch1(i32 %s) {
147; CHECK-LABEL: @switch1(
148; CHECK-NEXT:  entry:
149; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[S:%.*]], 0
150; CHECK-NEXT:    br i1 [[CMP]], label [[NEGATIVE:%.*]], label [[OUT:%.*]]
151; CHECK:       negative:
152; CHECK-NEXT:    switch i32 [[S]], label [[OUT]] [
153; CHECK-NEXT:    i32 -2, label [[NEXT:%.*]]
154; CHECK-NEXT:    i32 -1, label [[NEXT]]
155; CHECK-NEXT:    ]
156; CHECK:       out:
157; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ -1, [[NEGATIVE]] ]
158; CHECK-NEXT:    ret i32 [[P]]
159; CHECK:       next:
160; CHECK-NEXT:    ret i32 0
161;
162entry:
163  %cmp = icmp slt i32 %s, 0
164  br i1 %cmp, label %negative, label %out
165
166negative:
167  switch i32 %s, label %out [
168  i32 0, label %out
169  i32 1, label %out
170  i32 -1, label %next
171  i32 -2, label %next
172  i32 2, label %out
173  i32 3, label %out
174  ]
175
176out:
177  %p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ]
178  ret i32 %p
179
180next:
181  %q = phi i32 [ 0, %negative ], [ 0, %negative ]
182  ret i32 %q
183}
184
185define i32 @switch2(i32 %s) {
186; CHECK-LABEL: @switch2(
187; CHECK-NEXT:  entry:
188; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[S:%.*]], 0
189; CHECK-NEXT:    br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]]
190; CHECK:       positive:
191; CHECK-NEXT:    br label [[OUT]]
192; CHECK:       out:
193; CHECK-NEXT:    [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ]
194; CHECK-NEXT:    ret i32 [[P]]
195; CHECK:       next:
196; CHECK-NEXT:    ret i32 0
197;
198entry:
199  %cmp = icmp sgt i32 %s, 0
200  br i1 %cmp, label %positive, label %out
201
202positive:
203  switch i32 %s, label %out [
204  i32 0, label %out
205  i32 -1, label %next
206  i32 -2, label %next
207  ]
208
209out:
210  %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
211  ret i32 %p
212
213next:
214  %q = phi i32 [ 0, %positive ], [ 0, %positive ]
215  ret i32 %q
216}
217
218define i32 @switch3(i32 %s) {
219; CHECK-LABEL: @switch3(
220; CHECK-NEXT:  entry:
221; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[S:%.*]], 0
222; CHECK-NEXT:    br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]]
223; CHECK:       positive:
224; CHECK-NEXT:    br label [[OUT]]
225; CHECK:       out:
226; CHECK-NEXT:    [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ]
227; CHECK-NEXT:    ret i32 [[P]]
228; CHECK:       next:
229; CHECK-NEXT:    ret i32 0
230;
231entry:
232  %cmp = icmp sgt i32 %s, 0
233  br i1 %cmp, label %positive, label %out
234
235positive:
236  switch i32 %s, label %out [
237  i32 -1, label %out
238  i32 -2, label %next
239  i32 -3, label %next
240  ]
241
242out:
243  %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
244  ret i32 %p
245
246next:
247  %q = phi i32 [ 0, %positive ], [ 0, %positive ]
248  ret i32 %q
249}
250
251define void @switch4(i32 %s) {
252; CHECK-LABEL: @switch4(
253; CHECK-NEXT:  entry:
254; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[S:%.*]], 0
255; CHECK-NEXT:    br i1 [[CMP]], label [[ZERO:%.*]], label [[OUT:%.*]]
256; CHECK:       zero:
257; CHECK-NEXT:    br label [[NEXT:%.*]]
258; CHECK:       out:
259; CHECK-NEXT:    ret void
260; CHECK:       next:
261; CHECK-NEXT:    ret void
262;
263entry:
264  %cmp = icmp eq i32 %s, 0
265  br i1 %cmp, label %zero, label %out
266
267zero:
268  switch i32 %s, label %out [
269  i32 0, label %next
270  i32 1, label %out
271  i32 -1, label %out
272  ]
273
274out:
275  ret void
276
277next:
278  ret void
279}
280
281define i1 @arg_attribute(i8* nonnull %a) {
282; CHECK-LABEL: @arg_attribute(
283; CHECK-NEXT:    ret i1 false
284;
285  %cmp = icmp eq i8* %a, null
286  ret i1 %cmp
287}
288
289declare nonnull i8* @return_nonnull()
290define i1 @call_attribute() {
291; CHECK-LABEL: @call_attribute(
292; CHECK-NEXT:    [[A:%.*]] = call i8* @return_nonnull()
293; CHECK-NEXT:    ret i1 false
294;
295  %a = call i8* @return_nonnull()
296  %cmp = icmp eq i8* %a, null
297  ret i1 %cmp
298}
299
300define i1 @umin(i32 %a, i32 %b) {
301; CHECK-LABEL: @umin(
302; CHECK-NEXT:  entry:
303; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5
304; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
305; CHECK:       a_guard:
306; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20
307; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
308; CHECK:       b_guard:
309; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ult i32 [[A]], [[B]]
310; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
311; CHECK-NEXT:    ret i1 false
312; CHECK:       out:
313; CHECK-NEXT:    ret i1 false
314;
315entry:
316  %cmp = icmp ult i32 %a, 5
317  br i1 %cmp, label %a_guard, label %out
318
319a_guard:
320  %cmp2 = icmp ult i32 %b, 20
321  br i1 %cmp2, label %b_guard, label %out
322
323b_guard:
324  %sel_cmp = icmp ult i32 %a, %b
325  %min = select i1 %sel_cmp, i32 %a, i32 %b
326  %res = icmp eq i32 %min, 7
327  ret i1 %res
328out:
329  ret i1 false
330}
331
332define i1 @smin(i32 %a, i32 %b) {
333; CHECK-LABEL: @smin(
334; CHECK-NEXT:  entry:
335; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5
336; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
337; CHECK:       a_guard:
338; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20
339; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
340; CHECK:       b_guard:
341; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sle i32 [[A]], [[B]]
342; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
343; CHECK-NEXT:    ret i1 false
344; CHECK:       out:
345; CHECK-NEXT:    ret i1 false
346;
347entry:
348  %cmp = icmp ult i32 %a, 5
349  br i1 %cmp, label %a_guard, label %out
350
351a_guard:
352  %cmp2 = icmp ult i32 %b, 20
353  br i1 %cmp2, label %b_guard, label %out
354
355b_guard:
356  %sel_cmp = icmp sle i32 %a, %b
357  %min = select i1 %sel_cmp, i32 %a, i32 %b
358  %res = icmp eq i32 %min, 7
359  ret i1 %res
360out:
361  ret i1 false
362}
363
364define i1 @smax(i32 %a, i32 %b) {
365; CHECK-LABEL: @smax(
366; CHECK-NEXT:  entry:
367; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5
368; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
369; CHECK:       a_guard:
370; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20
371; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
372; CHECK:       b_guard:
373; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sge i32 [[A]], [[B]]
374; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
375; CHECK-NEXT:    ret i1 false
376; CHECK:       out:
377; CHECK-NEXT:    ret i1 false
378;
379entry:
380  %cmp = icmp sgt i32 %a, 5
381  br i1 %cmp, label %a_guard, label %out
382
383a_guard:
384  %cmp2 = icmp sgt i32 %b, 20
385  br i1 %cmp2, label %b_guard, label %out
386
387b_guard:
388  %sel_cmp = icmp sge i32 %a, %b
389  %max = select i1 %sel_cmp, i32 %a, i32 %b
390  %res = icmp eq i32 %max, 7
391  ret i1 %res
392out:
393  ret i1 false
394}
395
396define i1 @umax(i32 %a, i32 %b) {
397; CHECK-LABEL: @umax(
398; CHECK-NEXT:  entry:
399; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5
400; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
401; CHECK:       a_guard:
402; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20
403; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
404; CHECK:       b_guard:
405; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]]
406; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
407; CHECK-NEXT:    ret i1 false
408; CHECK:       out:
409; CHECK-NEXT:    ret i1 false
410;
411entry:
412  %cmp = icmp sgt i32 %a, 5
413  br i1 %cmp, label %a_guard, label %out
414
415a_guard:
416  %cmp2 = icmp sgt i32 %b, 20
417  br i1 %cmp2, label %b_guard, label %out
418
419b_guard:
420  %sel_cmp = icmp uge i32 %a, %b
421  %max = select i1 %sel_cmp, i32 %a, i32 %b
422  %res = icmp eq i32 %max, 7
423  ret i1 %res
424out:
425  ret i1 false
426}
427
428define i1 @clamp_low1(i32 %a) {
429; CHECK-LABEL: @clamp_low1(
430; CHECK-NEXT:  entry:
431; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
432; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
433; CHECK:       a_guard:
434; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
435; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
436; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[A]]
437; CHECK-NEXT:    ret i1 false
438; CHECK:       out:
439; CHECK-NEXT:    ret i1 false
440;
441entry:
442  %cmp = icmp sge i32 %a, 5
443  br i1 %cmp, label %a_guard, label %out
444
445a_guard:
446  %sel_cmp = icmp eq i32 %a, 5
447  %add = add i32 %a, -1
448  %sel = select i1 %sel_cmp, i32 5, i32 %a
449  %res = icmp eq i32 %sel, 4
450  ret i1 %res
451out:
452  ret i1 false
453}
454
455define i1 @clamp_low2(i32 %a) {
456; CHECK-LABEL: @clamp_low2(
457; CHECK-NEXT:  entry:
458; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
459; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
460; CHECK:       a_guard:
461; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
462; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
463; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 5
464; CHECK-NEXT:    ret i1 false
465; CHECK:       out:
466; CHECK-NEXT:    ret i1 false
467;
468entry:
469  %cmp = icmp sge i32 %a, 5
470  br i1 %cmp, label %a_guard, label %out
471
472a_guard:
473  %sel_cmp = icmp ne i32 %a, 5
474  %add = add i32 %a, -1
475  %sel = select i1 %sel_cmp, i32 %a, i32 5
476  %res = icmp eq i32 %sel, 4
477  ret i1 %res
478out:
479  ret i1 false
480}
481
482define i1 @clamp_high1(i32 %a) {
483; CHECK-LABEL: @clamp_high1(
484; CHECK-NEXT:  entry:
485; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
486; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
487; CHECK:       a_guard:
488; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
489; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
490; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[A]]
491; CHECK-NEXT:    ret i1 false
492; CHECK:       out:
493; CHECK-NEXT:    ret i1 false
494;
495entry:
496  %cmp = icmp sle i32 %a, 5
497  br i1 %cmp, label %a_guard, label %out
498
499a_guard:
500  %sel_cmp = icmp eq i32 %a, 5
501  %add = add i32 %a, 1
502  %sel = select i1 %sel_cmp, i32 5, i32 %a
503  %res = icmp eq i32 %sel, 6
504  ret i1 %res
505out:
506  ret i1 false
507}
508
509define i1 @clamp_high2(i32 %a) {
510; CHECK-LABEL: @clamp_high2(
511; CHECK-NEXT:  entry:
512; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
513; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
514; CHECK:       a_guard:
515; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
516; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
517; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 5
518; CHECK-NEXT:    ret i1 false
519; CHECK:       out:
520; CHECK-NEXT:    ret i1 false
521;
522entry:
523  %cmp = icmp sle i32 %a, 5
524  br i1 %cmp, label %a_guard, label %out
525
526a_guard:
527  %sel_cmp = icmp ne i32 %a, 5
528  %add = add i32 %a, 1
529  %sel = select i1 %sel_cmp, i32 %a, i32 5
530  %res = icmp eq i32 %sel, 6
531  ret i1 %res
532out:
533  ret i1 false
534}
535
536; Just showing arbitrary constants work, not really a clamp
537define i1 @clamp_high3(i32 %a) {
538; CHECK-LABEL: @clamp_high3(
539; CHECK-NEXT:  entry:
540; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
541; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
542; CHECK:       a_guard:
543; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
544; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 100
545; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 5
546; CHECK-NEXT:    ret i1 false
547; CHECK:       out:
548; CHECK-NEXT:    ret i1 false
549;
550entry:
551  %cmp = icmp sle i32 %a, 5
552  br i1 %cmp, label %a_guard, label %out
553
554a_guard:
555  %sel_cmp = icmp ne i32 %a, 5
556  %add = add i32 %a, 100
557  %sel = select i1 %sel_cmp, i32 %a, i32 5
558  %res = icmp eq i32 %sel, 105
559  ret i1 %res
560out:
561  ret i1 false
562}
563
564define void @abs1(i32 %a, i1* %p) {
565; CHECK-LABEL: @abs1(
566; CHECK-NEXT:  entry:
567; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
568; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
569; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
570; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
571; CHECK:       guard:
572; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
573; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 0
574; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
575; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
576; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[ABS]], 19
577; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
578; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
579; CHECK-NEXT:    [[C4:%.*]] = icmp sge i32 [[ABS]], 1
580; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
581; CHECK-NEXT:    br label [[EXIT]]
582; CHECK:       exit:
583; CHECK-NEXT:    ret void
584;
585entry:
586  %cmp1 = icmp slt i32 %a, 10
587  %cmp2 = icmp sgt i32 %a, -20
588  %and = and i1 %cmp1, %cmp2
589  br i1 %and, label %guard, label %exit
590
591guard:
592  %sub = sub i32 0, %a
593  %cmp = icmp slt i32 %a, 0
594  %abs = select i1 %cmp, i32 %sub, i32 %a
595  %c1 = icmp slt i32 %abs, 20
596  store i1 %c1, i1* %p
597  %c2 = icmp slt i32 %abs, 19
598  store i1 %c2, i1* %p
599  %c3 = icmp sge i32 %abs, 0
600  store i1 %c3, i1* %p
601  %c4 = icmp sge i32 %abs, 1
602  store i1 %c4, i1* %p
603  br label %exit
604
605exit:
606  ret void
607}
608
609define void @abs2(i32 %a, i1* %p) {
610; CHECK-LABEL: @abs2(
611; CHECK-NEXT:  entry:
612; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
613; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
614; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
615; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
616; CHECK:       guard:
617; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
618; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A]], 0
619; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
620; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
621; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[ABS]], 19
622; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
623; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
624; CHECK-NEXT:    [[C4:%.*]] = icmp sge i32 [[ABS]], 1
625; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
626; CHECK-NEXT:    br label [[EXIT]]
627; CHECK:       exit:
628; CHECK-NEXT:    ret void
629;
630entry:
631  %cmp1 = icmp slt i32 %a, 10
632  %cmp2 = icmp sgt i32 %a, -20
633  %and = and i1 %cmp1, %cmp2
634  br i1 %and, label %guard, label %exit
635
636guard:
637  %sub = sub i32 0, %a
638  %cmp = icmp sge i32 %a, 0
639  %abs = select i1 %cmp, i32 %a, i32 %sub
640  %c1 = icmp slt i32 %abs, 20
641  store i1 %c1, i1* %p
642  %c2 = icmp slt i32 %abs, 19
643  store i1 %c2, i1* %p
644  %c3 = icmp sge i32 %abs, 0
645  store i1 %c3, i1* %p
646  %c4 = icmp sge i32 %abs, 1
647  store i1 %c4, i1* %p
648  br label %exit
649
650exit:
651  ret void
652}
653
654define void @nabs1(i32 %a, i1* %p) {
655; CHECK-LABEL: @nabs1(
656; CHECK-NEXT:  entry:
657; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
658; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
659; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
660; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
661; CHECK:       guard:
662; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
663; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 0
664; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
665; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
666; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
667; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
668; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
669; CHECK-NEXT:    [[C4:%.*]] = icmp sle i32 [[NABS]], -1
670; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
671; CHECK-NEXT:    br label [[EXIT]]
672; CHECK:       exit:
673; CHECK-NEXT:    ret void
674;
675entry:
676  %cmp1 = icmp slt i32 %a, 10
677  %cmp2 = icmp sgt i32 %a, -20
678  %and = and i1 %cmp1, %cmp2
679  br i1 %and, label %guard, label %exit
680
681guard:
682  %sub = sub i32 0, %a
683  %cmp = icmp sgt i32 %a, 0
684  %nabs = select i1 %cmp, i32 %sub, i32 %a
685  %c1 = icmp sgt i32 %nabs, -20
686  store i1 %c1, i1* %p
687  %c2 = icmp sgt i32 %nabs, -19
688  store i1 %c2, i1* %p
689  %c3 = icmp sle i32 %nabs, 0
690  store i1 %c3, i1* %p
691  %c4 = icmp sle i32 %nabs, -1
692  store i1 %c4, i1* %p
693  br label %exit
694
695exit:
696  ret void
697}
698
699define void @nabs2(i32 %a, i1* %p) {
700; CHECK-LABEL: @nabs2(
701; CHECK-NEXT:  entry:
702; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
703; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
704; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
705; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
706; CHECK:       guard:
707; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
708; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 0
709; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
710; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
711; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
712; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
713; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
714; CHECK-NEXT:    [[C4:%.*]] = icmp sle i32 [[NABS]], -1
715; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
716; CHECK-NEXT:    br label [[EXIT]]
717; CHECK:       exit:
718; CHECK-NEXT:    ret void
719;
720entry:
721  %cmp1 = icmp slt i32 %a, 10
722  %cmp2 = icmp sgt i32 %a, -20
723  %and = and i1 %cmp1, %cmp2
724  br i1 %and, label %guard, label %exit
725
726guard:
727  %sub = sub i32 0, %a
728  %cmp = icmp slt i32 %a, 0
729  %nabs = select i1 %cmp, i32 %a, i32 %sub
730  %c1 = icmp sgt i32 %nabs, -20
731  store i1 %c1, i1* %p
732  %c2 = icmp sgt i32 %nabs, -19
733  store i1 %c2, i1* %p
734  %c3 = icmp sle i32 %nabs, 0
735  store i1 %c3, i1* %p
736  %c4 = icmp sle i32 %nabs, -1
737  store i1 %c4, i1* %p
738  br label %exit
739
740exit:
741  ret void
742}
743
744define i1 @zext_unknown(i8 %a) {
745; CHECK-LABEL: @zext_unknown(
746; CHECK-NEXT:  entry:
747; CHECK-NEXT:    [[A32:%.*]] = zext i8 [[A:%.*]] to i32
748; CHECK-NEXT:    ret i1 true
749;
750entry:
751  %a32 = zext i8 %a to i32
752  %cmp = icmp sle i32 %a32, 256
753  ret i1 %cmp
754}
755
756define i1 @trunc_unknown(i32 %a) {
757; CHECK-LABEL: @trunc_unknown(
758; CHECK-NEXT:  entry:
759; CHECK-NEXT:    [[A8:%.*]] = trunc i32 [[A:%.*]] to i8
760; CHECK-NEXT:    [[A32:%.*]] = sext i8 [[A8]] to i32
761; CHECK-NEXT:    ret i1 true
762;
763entry:
764  %a8 = trunc i32 %a to i8
765  %a32 = sext i8 %a8 to i32
766  %cmp = icmp sle i32 %a32, 128
767  ret i1 %cmp
768}
769
770; TODO: missed optimization
771; Make sure we exercise non-integer inputs to unary operators (i.e. crash check).
772define i1 @bitcast_unknown(float %a) {
773; CHECK-LABEL: @bitcast_unknown(
774; CHECK-NEXT:  entry:
775; CHECK-NEXT:    [[A32:%.*]] = bitcast float [[A:%.*]] to i32
776; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A32]], 128
777; CHECK-NEXT:    ret i1 [[CMP]]
778;
779entry:
780  %a32 = bitcast float %a to i32
781  %cmp = icmp sle i32 %a32, 128
782  ret i1 %cmp
783}
784
785define i1 @bitcast_unknown2(i8* %p) {
786; CHECK-LABEL: @bitcast_unknown2(
787; CHECK-NEXT:  entry:
788; CHECK-NEXT:    [[P64:%.*]] = ptrtoint i8* [[P:%.*]] to i64
789; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i64 [[P64]], 128
790; CHECK-NEXT:    ret i1 [[CMP]]
791;
792entry:
793  %p64 = ptrtoint i8* %p to i64
794  %cmp = icmp sle i64 %p64, 128
795  ret i1 %cmp
796}
797
798
799define i1 @and_unknown(i32 %a) {
800; CHECK-LABEL: @and_unknown(
801; CHECK-NEXT:  entry:
802; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 128
803; CHECK-NEXT:    ret i1 true
804;
805entry:
806  %and = and i32 %a, 128
807  %cmp = icmp sle i32 %and, 128
808  ret i1 %cmp
809}
810
811define i1 @lshr_unknown(i32 %a) {
812; CHECK-LABEL: @lshr_unknown(
813; CHECK-NEXT:  entry:
814; CHECK-NEXT:    [[AND:%.*]] = lshr i32 [[A:%.*]], 30
815; CHECK-NEXT:    ret i1 true
816;
817entry:
818  %and = lshr i32 %a, 30
819  %cmp = icmp sle i32 %and, 128
820  ret i1 %cmp
821}
822
823define i1 @urem_unknown(i32 %a) {
824; CHECK-LABEL: @urem_unknown(
825; CHECK-NEXT:  entry:
826; CHECK-NEXT:    [[UREM:%.*]] = urem i32 [[A:%.*]], 30
827; CHECK-NEXT:    ret i1 true
828;
829entry:
830  %urem = urem i32 %a, 30
831  %cmp = icmp ult i32 %urem, 30
832  ret i1 %cmp
833}
834
835define i1 @srem_unknown(i32 %a) {
836; CHECK-LABEL: @srem_unknown(
837; CHECK-NEXT:  entry:
838; CHECK-NEXT:    [[SREM:%.*]] = srem i32 [[A:%.*]], 30
839; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
840; CHECK:       exit1:
841; CHECK-NEXT:    ret i1 true
842; CHECK:       exit2:
843; CHECK-NEXT:    ret i1 true
844;
845entry:
846  %srem = srem i32 %a, 30
847  %cmp1 = icmp slt i32 %srem, 30
848  %cmp2 = icmp sgt i32 %srem, -30
849  br i1 undef, label %exit1, label %exit2
850exit1:
851  ret i1 %cmp1
852exit2:
853  ret i1 %cmp2
854}
855
856define i1 @sdiv_unknown(i32 %a) {
857; CHECK-LABEL: @sdiv_unknown(
858; CHECK-NEXT:  entry:
859; CHECK-NEXT:    [[SREM:%.*]] = sdiv i32 [[A:%.*]], 123
860; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
861; CHECK:       exit1:
862; CHECK-NEXT:    ret i1 true
863; CHECK:       exit2:
864; CHECK-NEXT:    ret i1 true
865;
866entry:
867  %srem = sdiv i32 %a, 123
868  %cmp1 = icmp slt i32 %srem, 17459217
869  %cmp2 = icmp sgt i32 %srem, -17459217
870  br i1 undef, label %exit1, label %exit2
871exit1:
872  ret i1 %cmp1
873exit2:
874  ret i1 %cmp2
875}
876
877define i1 @uadd_sat_unknown(i32 %a) {
878; CHECK-LABEL: @uadd_sat_unknown(
879; CHECK-NEXT:  entry:
880; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[A:%.*]], i32 100)
881; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[VAL]], 100
882; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
883; CHECK:       exit1:
884; CHECK-NEXT:    ret i1 true
885; CHECK:       exit2:
886; CHECK-NEXT:    ret i1 [[CMP2]]
887;
888entry:
889  %val = call i32 @llvm.uadd.sat.i32(i32 %a, i32 100)
890  %cmp1 = icmp uge i32 %val, 100
891  %cmp2 = icmp ugt i32 %val, 100
892  br i1 undef, label %exit1, label %exit2
893exit1:
894  ret i1 %cmp1
895exit2:
896  ret i1 %cmp2
897}
898
899define i1 @usub_sat_unknown(i32 %a) {
900; CHECK-LABEL: @usub_sat_unknown(
901; CHECK-NEXT:  entry:
902; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 100)
903; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[VAL]], -101
904; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
905; CHECK:       exit1:
906; CHECK-NEXT:    ret i1 true
907; CHECK:       exit2:
908; CHECK-NEXT:    ret i1 [[CMP2]]
909;
910entry:
911  %val = call i32 @llvm.usub.sat.i32(i32 %a, i32 100)
912  %cmp1 = icmp ule i32 %val, 4294967195
913  %cmp2 = icmp ult i32 %val, 4294967195
914  br i1 undef, label %exit1, label %exit2
915exit1:
916  ret i1 %cmp1
917exit2:
918  ret i1 %cmp2
919}
920
921define i1 @sadd_sat_unknown(i32 %a) {
922; CHECK-LABEL: @sadd_sat_unknown(
923; CHECK-NEXT:  entry:
924; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A:%.*]], i32 100)
925; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[VAL]], -2147483548
926; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
927; CHECK:       exit1:
928; CHECK-NEXT:    ret i1 true
929; CHECK:       exit2:
930; CHECK-NEXT:    ret i1 [[CMP2]]
931;
932entry:
933  %val = call i32 @llvm.sadd.sat.i32(i32 %a, i32 100)
934  %cmp1 = icmp sge i32 %val, -2147483548
935  %cmp2 = icmp sgt i32 %val, -2147483548
936  br i1 undef, label %exit1, label %exit2
937exit1:
938  ret i1 %cmp1
939exit2:
940  ret i1 %cmp2
941}
942
943define i1 @ssub_sat_unknown(i32 %a) {
944; CHECK-LABEL: @ssub_sat_unknown(
945; CHECK-NEXT:  entry:
946; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 100)
947; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[VAL]], 2147483547
948; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
949; CHECK:       exit1:
950; CHECK-NEXT:    ret i1 true
951; CHECK:       exit2:
952; CHECK-NEXT:    ret i1 [[CMP2]]
953;
954entry:
955  %val = call i32 @llvm.ssub.sat.i32(i32 %a, i32 100)
956  %cmp1 = icmp sle i32 %val, 2147483547
957  %cmp2 = icmp slt i32 %val, 2147483547
958  br i1 undef, label %exit1, label %exit2
959exit1:
960  ret i1 %cmp1
961exit2:
962  ret i1 %cmp2
963}
964
965declare i32 @llvm.uadd.sat.i32(i32, i32)
966declare i32 @llvm.usub.sat.i32(i32, i32)
967declare i32 @llvm.sadd.sat.i32(i32, i32)
968declare i32 @llvm.ssub.sat.i32(i32, i32)
969