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 @umin(i32 %a, i32 %b) {
204; CHECK-LABEL: @umin(
205entry:
206  %cmp = icmp ult i32 %a, 5
207  br i1 %cmp, label %a_guard, label %out
208
209a_guard:
210  %cmp2 = icmp ult i32 %b, 20
211  br i1 %cmp2, label %b_guard, label %out
212
213b_guard:
214  %sel_cmp = icmp ult i32 %a, %b
215  %min = select i1 %sel_cmp, i32 %a, i32 %b
216  %res = icmp eq i32 %min, 7
217  br label %next
218next:
219; CHECK: next:
220; CHECK: ret i1 false
221  ret i1 %res
222out:
223  ret i1 false
224}
225
226define i1 @smin(i32 %a, i32 %b) {
227; CHECK-LABEL: @smin(
228entry:
229  %cmp = icmp ult i32 %a, 5
230  br i1 %cmp, label %a_guard, label %out
231
232a_guard:
233  %cmp2 = icmp ult i32 %b, 20
234  br i1 %cmp2, label %b_guard, label %out
235
236b_guard:
237  %sel_cmp = icmp sle i32 %a, %b
238  %min = select i1 %sel_cmp, i32 %a, i32 %b
239  %res = icmp eq i32 %min, 7
240  br label %next
241next:
242; CHECK: next:
243; CHECK: ret i1 false
244  ret i1 %res
245out:
246  ret i1 false
247}
248
249define i1 @smax(i32 %a, i32 %b) {
250; CHECK-LABEL: @smax(
251entry:
252  %cmp = icmp sgt i32 %a, 5
253  br i1 %cmp, label %a_guard, label %out
254
255a_guard:
256  %cmp2 = icmp sgt i32 %b, 20
257  br i1 %cmp2, label %b_guard, label %out
258
259b_guard:
260  %sel_cmp = icmp sge i32 %a, %b
261  %max = select i1 %sel_cmp, i32 %a, i32 %b
262  %res = icmp eq i32 %max, 7
263  br label %next
264next:
265; CHECK: next:
266; CHECK: ret i1 false
267  ret i1 %res
268out:
269  ret i1 false
270}
271
272define i1 @umax(i32 %a, i32 %b) {
273; CHECK-LABEL: @umax(
274entry:
275  %cmp = icmp sgt i32 %a, 5
276  br i1 %cmp, label %a_guard, label %out
277
278a_guard:
279  %cmp2 = icmp sgt i32 %b, 20
280  br i1 %cmp2, label %b_guard, label %out
281
282b_guard:
283  %sel_cmp = icmp uge i32 %a, %b
284  %max = select i1 %sel_cmp, i32 %a, i32 %b
285  %res = icmp eq i32 %max, 7
286  br label %next
287next:
288; CHECK: next:
289; CHECK: ret i1 false
290  ret i1 %res
291out:
292  ret i1 false
293}
294
295define i1 @clamp_low1(i32 %a) {
296; CHECK-LABEL: @clamp_low1(
297entry:
298  %cmp = icmp sge i32 %a, 5
299  br i1 %cmp, label %a_guard, label %out
300
301a_guard:
302  %sel_cmp = icmp eq i32 %a, 5
303  %add = add i32 %a, -1
304  %sel = select i1 %sel_cmp, i32 5, i32 %a
305  %res = icmp eq i32 %sel, 4
306  br label %next
307next:
308; CHECK: next:
309; CHECK: ret i1 false
310  ret i1 %res
311out:
312  ret i1 false
313}
314
315define i1 @clamp_low2(i32 %a) {
316; CHECK-LABEL: @clamp_low2(
317entry:
318  %cmp = icmp sge i32 %a, 5
319  br i1 %cmp, label %a_guard, label %out
320
321a_guard:
322  %sel_cmp = icmp ne i32 %a, 5
323  %add = add i32 %a, -1
324  %sel = select i1 %sel_cmp, i32 %a, i32 5
325  %res = icmp eq i32 %sel, 4
326  br label %next
327next:
328; CHECK: next:
329; CHECK: ret i1 false
330  ret i1 %res
331out:
332  ret i1 false
333}
334
335define i1 @clamp_high1(i32 %a) {
336; CHECK-LABEL: @clamp_high1(
337entry:
338  %cmp = icmp sle i32 %a, 5
339  br i1 %cmp, label %a_guard, label %out
340
341a_guard:
342  %sel_cmp = icmp eq i32 %a, 5
343  %add = add i32 %a, 1
344  %sel = select i1 %sel_cmp, i32 5, i32 %a
345  %res = icmp eq i32 %sel, 6
346  br label %next
347next:
348; CHECK: next:
349; CHECK: ret i1 false
350  ret i1 %res
351out:
352  ret i1 false
353}
354
355define i1 @clamp_high2(i32 %a) {
356; CHECK-LABEL: @clamp_high2(
357entry:
358  %cmp = icmp sle i32 %a, 5
359  br i1 %cmp, label %a_guard, label %out
360
361a_guard:
362  %sel_cmp = icmp ne i32 %a, 5
363  %add = add i32 %a, 1
364  %sel = select i1 %sel_cmp, i32 %a, i32 5
365  %res = icmp eq i32 %sel, 6
366  br label %next
367next:
368; CHECK: next:
369; CHECK: ret i1 false
370  ret i1 %res
371out:
372  ret i1 false
373}
374
375; Just showing arbitrary constants work, not really a clamp
376define i1 @clamp_high3(i32 %a) {
377; CHECK-LABEL: @clamp_high3(
378entry:
379  %cmp = icmp sle i32 %a, 5
380  br i1 %cmp, label %a_guard, label %out
381
382a_guard:
383  %sel_cmp = icmp ne i32 %a, 5
384  %add = add i32 %a, 100
385  %sel = select i1 %sel_cmp, i32 %a, i32 5
386  %res = icmp eq i32 %sel, 105
387  br label %next
388next:
389; CHECK: next:
390; CHECK: ret i1 false
391  ret i1 %res
392out:
393  ret i1 false
394}
395