1; RUN: opt < %s -correlated-propagation -S | FileCheck %s
2; PR2581
3
4; CHECK-LABEL: @test1(
5define i32 @test1(i1 %C) nounwind  {
6        br i1 %C, label %exit, label %body
7
8body:           ; preds = %0
9; CHECK-NOT: select
10        %A = select i1 %C, i32 10, i32 11               ; <i32> [#uses=1]
11; CHECK: ret i32 11
12        ret i32 %A
13
14exit:           ; preds = %0
15; CHECK: ret i32 10
16        ret i32 10
17}
18
19; PR4420
20declare i1 @ext()
21; CHECK-LABEL: @test2(
22define i1 @test2() {
23entry:
24        %cond = tail call i1 @ext()             ; <i1> [#uses=2]
25        br i1 %cond, label %bb1, label %bb2
26
27bb1:            ; preds = %entry
28        %cond2 = tail call i1 @ext()            ; <i1> [#uses=1]
29        br i1 %cond2, label %bb3, label %bb2
30
31bb2:            ; preds = %bb1, %entry
32; CHECK-NOT: phi i1
33        %cond_merge = phi i1 [ %cond, %entry ], [ false, %bb1 ]         ; <i1> [#uses=1]
34; CHECK: ret i1 false
35        ret i1 %cond_merge
36
37bb3:            ; preds = %bb1
38        %res = tail call i1 @ext()              ; <i1> [#uses=1]
39; CHECK: ret i1 %res
40        ret i1 %res
41}
42
43; PR4855
44@gv = internal constant i8 7
45; CHECK-LABEL: @test3(
46define i8 @test3(i8* %a) nounwind {
47entry:
48        %cond = icmp eq i8* %a, @gv
49        br i1 %cond, label %bb2, label %bb
50
51bb:             ; preds = %entry
52        ret i8 0
53
54bb2:            ; preds = %entry
55; CHECK: %should_be_const = load i8, i8* @gv
56        %should_be_const = load i8, i8* %a
57        ret i8 %should_be_const
58}
59
60; PR1757
61; CHECK-LABEL: @test4(
62define i32 @test4(i32) {
63EntryBlock:
64; CHECK: icmp sgt i32 %0, 2
65  %.demorgan = icmp sgt i32 %0, 2
66  br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo
67
68GreaterThanTwo:
69; CHECK-NOT: icmp eq i32 %0, 2
70  icmp eq i32 %0, 2
71; CHECK: br i1 false
72  br i1 %1, label %Impossible, label %NotTwoAndGreaterThanTwo
73
74NotTwoAndGreaterThanTwo:
75  ret i32 2
76
77Impossible:
78  ret i32 1
79
80LessThanOrEqualToTwo:
81  ret i32 0
82}
83
84declare i32* @f(i32*)
85define void @test5(i32* %x, i32* %y) {
86; CHECK-LABEL: @test5(
87entry:
88  %pre = icmp eq i32* %x, null
89  br i1 %pre, label %return, label %loop
90
91loop:
92  %phi = phi i32* [ %sel, %loop ], [ %x, %entry ]
93; CHECK: %phi = phi i32* [ %f, %loop ], [ %x, %entry ]
94  %f = tail call i32* @f(i32* %phi)
95  %cmp1 = icmp ne i32* %f, %y
96  %sel = select i1 %cmp1, i32* %f, i32* null
97  %cmp2 = icmp eq i32* %sel, null
98  br i1 %cmp2, label %return, label %loop
99
100return:
101  ret void
102}
103
104define i32 @switch1(i32 %s) {
105; CHECK-LABEL: @switch1(
106entry:
107  %cmp = icmp slt i32 %s, 0
108  br i1 %cmp, label %negative, label %out
109
110negative:
111  switch i32 %s, label %out [
112; CHECK: switch i32 %s, label %out
113    i32 0, label %out
114; CHECK-NOT: i32 0
115    i32 1, label %out
116; CHECK-NOT: i32 1
117    i32 -1, label %next
118; CHECK: i32 -1, label %next
119    i32 -2, label %next
120; CHECK: i32 -2, label %next
121    i32 2, label %out
122; CHECK-NOT: i32 2
123    i32 3, label %out
124; CHECK-NOT: i32 3
125  ]
126
127out:
128  %p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ]
129  ret i32 %p
130
131next:
132  %q = phi i32 [ 0, %negative ], [ 0, %negative ]
133  ret i32 %q
134}
135
136define i32 @switch2(i32 %s) {
137; CHECK-LABEL: @switch2(
138entry:
139  %cmp = icmp sgt i32 %s, 0
140  br i1 %cmp, label %positive, label %out
141
142positive:
143  switch i32 %s, label %out [
144    i32 0, label %out
145    i32 -1, label %next
146    i32 -2, label %next
147  ]
148; CHECK: br label %out
149
150out:
151  %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
152  ret i32 %p
153
154next:
155  %q = phi i32 [ 0, %positive ], [ 0, %positive ]
156  ret i32 %q
157}
158
159define i32 @switch3(i32 %s) {
160; CHECK-LABEL: @switch3(
161entry:
162  %cmp = icmp sgt i32 %s, 0
163  br i1 %cmp, label %positive, label %out
164
165positive:
166  switch i32 %s, label %out [
167    i32 -1, label %out
168    i32 -2, label %next
169    i32 -3, label %next
170  ]
171; CHECK: br label %out
172
173out:
174  %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
175  ret i32 %p
176
177next:
178  %q = phi i32 [ 0, %positive ], [ 0, %positive ]
179  ret i32 %q
180}
181
182define void @switch4(i32 %s) {
183; CHECK-LABEL: @switch4(
184entry:
185  %cmp = icmp eq i32 %s, 0
186  br i1 %cmp, label %zero, label %out
187
188zero:
189  switch i32 %s, label %out [
190    i32 0, label %next
191    i32 1, label %out
192    i32 -1, label %out
193  ]
194; CHECK: br label %next
195
196out:
197  ret void
198
199next:
200  ret void
201}
202
203define i1 @arg_attribute(i8* nonnull %a) {
204; CHECK-LABEL: @arg_attribute(
205; CHECK: ret i1 false
206  %cmp = icmp eq i8* %a, null
207  br label %exit
208
209exit:
210  ret i1 %cmp
211}
212
213declare nonnull i8* @return_nonnull()
214define i1 @call_attribute() {
215; CHECK-LABEL: @call_attribute(
216; CHECK: ret i1 false
217  %a = call i8* @return_nonnull()
218  %cmp = icmp eq i8* %a, null
219  br label %exit
220
221exit:
222  ret i1 %cmp
223}
224
225define i1 @umin(i32 %a, i32 %b) {
226; CHECK-LABEL: @umin(
227entry:
228  %cmp = icmp ult i32 %a, 5
229  br i1 %cmp, label %a_guard, label %out
230
231a_guard:
232  %cmp2 = icmp ult i32 %b, 20
233  br i1 %cmp2, label %b_guard, label %out
234
235b_guard:
236  %sel_cmp = icmp ult i32 %a, %b
237  %min = select i1 %sel_cmp, i32 %a, i32 %b
238  %res = icmp eq i32 %min, 7
239  br label %next
240next:
241; CHECK: next:
242; CHECK: ret i1 false
243  ret i1 %res
244out:
245  ret i1 false
246}
247
248define i1 @smin(i32 %a, i32 %b) {
249; CHECK-LABEL: @smin(
250entry:
251  %cmp = icmp ult i32 %a, 5
252  br i1 %cmp, label %a_guard, label %out
253
254a_guard:
255  %cmp2 = icmp ult i32 %b, 20
256  br i1 %cmp2, label %b_guard, label %out
257
258b_guard:
259  %sel_cmp = icmp sle i32 %a, %b
260  %min = select i1 %sel_cmp, i32 %a, i32 %b
261  %res = icmp eq i32 %min, 7
262  br label %next
263next:
264; CHECK: next:
265; CHECK: ret i1 false
266  ret i1 %res
267out:
268  ret i1 false
269}
270
271define i1 @smax(i32 %a, i32 %b) {
272; CHECK-LABEL: @smax(
273entry:
274  %cmp = icmp sgt i32 %a, 5
275  br i1 %cmp, label %a_guard, label %out
276
277a_guard:
278  %cmp2 = icmp sgt i32 %b, 20
279  br i1 %cmp2, label %b_guard, label %out
280
281b_guard:
282  %sel_cmp = icmp sge i32 %a, %b
283  %max = select i1 %sel_cmp, i32 %a, i32 %b
284  %res = icmp eq i32 %max, 7
285  br label %next
286next:
287; CHECK: next:
288; CHECK: ret i1 false
289  ret i1 %res
290out:
291  ret i1 false
292}
293
294define i1 @umax(i32 %a, i32 %b) {
295; CHECK-LABEL: @umax(
296entry:
297  %cmp = icmp sgt i32 %a, 5
298  br i1 %cmp, label %a_guard, label %out
299
300a_guard:
301  %cmp2 = icmp sgt i32 %b, 20
302  br i1 %cmp2, label %b_guard, label %out
303
304b_guard:
305  %sel_cmp = icmp uge i32 %a, %b
306  %max = select i1 %sel_cmp, i32 %a, i32 %b
307  %res = icmp eq i32 %max, 7
308  br label %next
309next:
310; CHECK: next:
311; CHECK: ret i1 false
312  ret i1 %res
313out:
314  ret i1 false
315}
316
317define i1 @clamp_low1(i32 %a) {
318; CHECK-LABEL: @clamp_low1(
319entry:
320  %cmp = icmp sge i32 %a, 5
321  br i1 %cmp, label %a_guard, label %out
322
323a_guard:
324  %sel_cmp = icmp eq i32 %a, 5
325  %add = add i32 %a, -1
326  %sel = select i1 %sel_cmp, i32 5, i32 %a
327  %res = icmp eq i32 %sel, 4
328  br label %next
329next:
330; CHECK: next:
331; CHECK: ret i1 false
332  ret i1 %res
333out:
334  ret i1 false
335}
336
337define i1 @clamp_low2(i32 %a) {
338; CHECK-LABEL: @clamp_low2(
339entry:
340  %cmp = icmp sge i32 %a, 5
341  br i1 %cmp, label %a_guard, label %out
342
343a_guard:
344  %sel_cmp = icmp ne i32 %a, 5
345  %add = add i32 %a, -1
346  %sel = select i1 %sel_cmp, i32 %a, i32 5
347  %res = icmp eq i32 %sel, 4
348  br label %next
349next:
350; CHECK: next:
351; CHECK: ret i1 false
352  ret i1 %res
353out:
354  ret i1 false
355}
356
357define i1 @clamp_high1(i32 %a) {
358; CHECK-LABEL: @clamp_high1(
359entry:
360  %cmp = icmp sle i32 %a, 5
361  br i1 %cmp, label %a_guard, label %out
362
363a_guard:
364  %sel_cmp = icmp eq i32 %a, 5
365  %add = add i32 %a, 1
366  %sel = select i1 %sel_cmp, i32 5, i32 %a
367  %res = icmp eq i32 %sel, 6
368  br label %next
369next:
370; CHECK: next:
371; CHECK: ret i1 false
372  ret i1 %res
373out:
374  ret i1 false
375}
376
377define i1 @clamp_high2(i32 %a) {
378; CHECK-LABEL: @clamp_high2(
379entry:
380  %cmp = icmp sle i32 %a, 5
381  br i1 %cmp, label %a_guard, label %out
382
383a_guard:
384  %sel_cmp = icmp ne i32 %a, 5
385  %add = add i32 %a, 1
386  %sel = select i1 %sel_cmp, i32 %a, i32 5
387  %res = icmp eq i32 %sel, 6
388  br label %next
389next:
390; CHECK: next:
391; CHECK: ret i1 false
392  ret i1 %res
393out:
394  ret i1 false
395}
396
397; Just showing arbitrary constants work, not really a clamp
398define i1 @clamp_high3(i32 %a) {
399; CHECK-LABEL: @clamp_high3(
400entry:
401  %cmp = icmp sle i32 %a, 5
402  br i1 %cmp, label %a_guard, label %out
403
404a_guard:
405  %sel_cmp = icmp ne i32 %a, 5
406  %add = add i32 %a, 100
407  %sel = select i1 %sel_cmp, i32 %a, i32 5
408  %res = icmp eq i32 %sel, 105
409  br label %next
410next:
411; CHECK: next:
412; CHECK: ret i1 false
413  ret i1 %res
414out:
415  ret i1 false
416}
417
418define i1 @zext_unknown(i8 %a) {
419; CHECK-LABEL: @zext_unknown
420; CHECK: ret i1 true
421entry:
422  %a32 = zext i8 %a to i32
423  %cmp = icmp sle i32 %a32, 256
424  br label %exit
425exit:
426  ret i1 %cmp
427}
428
429define i1 @trunc_unknown(i32 %a) {
430; CHECK-LABEL: @trunc_unknown
431; CHECK: ret i1 true
432entry:
433  %a8 = trunc i32 %a to i8
434  %a32 = sext i8 %a8 to i32
435  %cmp = icmp sle i32 %a32, 128
436  br label %exit
437exit:
438  ret i1 %cmp
439}
440
441; TODO: missed optimization
442; Make sure we exercise non-integer inputs to unary operators (i.e. crash
443; check).
444define i1 @bitcast_unknown(float %a) {
445; CHECK-LABEL: @bitcast_unknown
446; CHECK: ret i1 %cmp
447entry:
448  %a32 = bitcast float %a to i32
449  %cmp = icmp sle i32 %a32, 128
450  br label %exit
451exit:
452  ret i1 %cmp
453}
454
455define i1 @bitcast_unknown2(i8* %p) {
456; CHECK-LABEL: @bitcast_unknown2
457; CHECK: ret i1 %cmp
458entry:
459  %p64 = ptrtoint i8* %p to i64
460  %cmp = icmp sle i64 %p64, 128
461  br label %exit
462exit:
463  ret i1 %cmp
464}
465
466
467define i1 @and_unknown(i32 %a) {
468; CHECK-LABEL: @and_unknown
469; CHECK: ret i1 true
470entry:
471  %and = and i32 %a, 128
472  %cmp = icmp sle i32 %and, 128
473  br label %exit
474exit:
475  ret i1 %cmp
476}
477
478define i1 @lshr_unknown(i32 %a) {
479; CHECK-LABEL: @lshr_unknown
480; CHECK: ret i1 true
481entry:
482  %and = lshr i32 %a, 30
483  %cmp = icmp sle i32 %and, 128
484  br label %exit
485exit:
486  ret i1 %cmp
487}
488