[PowerPC] Eliminate compares - add i32 sext/zext handling for SETULT/SETUGT
[llvm-core.git] / test / Transforms / CorrelatedValuePropagation / basic.ll
blob14b9a1999cc3ceab7308ed8441a6f2b09546829d
1 ; RUN: opt < %s -correlated-propagation -S | FileCheck %s
2 ; PR2581
4 ; CHECK-LABEL: @test1(
5 define i32 @test1(i1 %C) nounwind  {
6         br i1 %C, label %exit, label %body
8 body:           ; 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
14 exit:           ; preds = %0
15 ; CHECK: ret i32 10
16         ret i32 10
19 ; PR4420
20 declare i1 @ext()
21 ; CHECK-LABEL: @test2(
22 define i1 @test2() {
23 entry:
24         %cond = tail call i1 @ext()             ; <i1> [#uses=2]
25         br i1 %cond, label %bb1, label %bb2
27 bb1:            ; preds = %entry
28         %cond2 = tail call i1 @ext()            ; <i1> [#uses=1]
29         br i1 %cond2, label %bb3, label %bb2
31 bb2:            ; 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
37 bb3:            ; preds = %bb1
38         %res = tail call i1 @ext()              ; <i1> [#uses=1]
39 ; CHECK: ret i1 %res
40         ret i1 %res
43 ; PR4855
44 @gv = internal constant i8 7
45 ; CHECK-LABEL: @test3(
46 define i8 @test3(i8* %a) nounwind {
47 entry:
48         %cond = icmp eq i8* %a, @gv
49         br i1 %cond, label %bb2, label %bb
51 bb:             ; preds = %entry
52         ret i8 0
54 bb2:            ; 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
60 ; PR1757
61 ; CHECK-LABEL: @test4(
62 define i32 @test4(i32) {
63 EntryBlock:
64 ; CHECK: icmp sgt i32 %0, 2  
65   %.demorgan = icmp sgt i32 %0, 2    
66   br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo
68 GreaterThanTwo:
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
74 NotTwoAndGreaterThanTwo:
75   ret i32 2
77 Impossible:
78   ret i32 1
80 LessThanOrEqualToTwo:
81   ret i32 0
84 declare i32* @f(i32*)
85 define void @test5(i32* %x, i32* %y) {
86 ; CHECK-LABEL: @test5(
87 entry:
88   %pre = icmp eq i32* %x, null
89   br i1 %pre, label %return, label %loop
91 loop:
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
100 return:
101   ret void
104 define i32 @switch1(i32 %s) {
105 ; CHECK-LABEL: @switch1(
106 entry:
107   %cmp = icmp slt i32 %s, 0
108   br i1 %cmp, label %negative, label %out
110 negative:
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-DAG: i32 -1, label %next
119     i32 -2, label %next
120 ; CHECK-DAG: 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   ]
127 out:
128   %p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ]
129   ret i32 %p
131 next:
132   %q = phi i32 [ 0, %negative ], [ 0, %negative ]
133   ret i32 %q
136 define i32 @switch2(i32 %s) {
137 ; CHECK-LABEL: @switch2(
138 entry:
139   %cmp = icmp sgt i32 %s, 0
140   br i1 %cmp, label %positive, label %out
142 positive:
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
150 out:
151   %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
152   ret i32 %p
154 next:
155   %q = phi i32 [ 0, %positive ], [ 0, %positive ]
156   ret i32 %q
159 define i32 @switch3(i32 %s) {
160 ; CHECK-LABEL: @switch3(
161 entry:
162   %cmp = icmp sgt i32 %s, 0
163   br i1 %cmp, label %positive, label %out
165 positive:
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
173 out:
174   %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
175   ret i32 %p
177 next:
178   %q = phi i32 [ 0, %positive ], [ 0, %positive ]
179   ret i32 %q
182 define void @switch4(i32 %s) {
183 ; CHECK-LABEL: @switch4(
184 entry:
185   %cmp = icmp eq i32 %s, 0
186   br i1 %cmp, label %zero, label %out
188 zero:
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
196 out:
197   ret void
199 next:
200   ret void
203 define 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
209 exit:
210   ret i1 %cmp
213 declare nonnull i8* @return_nonnull()
214 define 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
221 exit:
222   ret i1 %cmp
225 define i1 @umin(i32 %a, i32 %b) {
226 ; CHECK-LABEL: @umin(
227 entry:
228   %cmp = icmp ult i32 %a, 5
229   br i1 %cmp, label %a_guard, label %out
231 a_guard:
232   %cmp2 = icmp ult i32 %b, 20
233   br i1 %cmp2, label %b_guard, label %out
235 b_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
240 next:
241 ; CHECK: next:
242 ; CHECK: ret i1 false
243   ret i1 %res
244 out:
245   ret i1 false
248 define i1 @smin(i32 %a, i32 %b) {
249 ; CHECK-LABEL: @smin(
250 entry:
251   %cmp = icmp ult i32 %a, 5
252   br i1 %cmp, label %a_guard, label %out
254 a_guard:
255   %cmp2 = icmp ult i32 %b, 20
256   br i1 %cmp2, label %b_guard, label %out
258 b_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
263 next:
264 ; CHECK: next:
265 ; CHECK: ret i1 false
266   ret i1 %res
267 out:
268   ret i1 false
271 define i1 @smax(i32 %a, i32 %b) {
272 ; CHECK-LABEL: @smax(
273 entry:
274   %cmp = icmp sgt i32 %a, 5
275   br i1 %cmp, label %a_guard, label %out
277 a_guard:
278   %cmp2 = icmp sgt i32 %b, 20
279   br i1 %cmp2, label %b_guard, label %out
281 b_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
286 next:
287 ; CHECK: next:
288 ; CHECK: ret i1 false
289   ret i1 %res
290 out:
291   ret i1 false
294 define i1 @umax(i32 %a, i32 %b) {
295 ; CHECK-LABEL: @umax(
296 entry:
297   %cmp = icmp sgt i32 %a, 5
298   br i1 %cmp, label %a_guard, label %out
300 a_guard:
301   %cmp2 = icmp sgt i32 %b, 20
302   br i1 %cmp2, label %b_guard, label %out
304 b_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
309 next:
310 ; CHECK: next:
311 ; CHECK: ret i1 false
312   ret i1 %res
313 out:
314   ret i1 false
317 define i1 @clamp_low1(i32 %a) {
318 ; CHECK-LABEL: @clamp_low1(
319 entry:
320   %cmp = icmp sge i32 %a, 5
321   br i1 %cmp, label %a_guard, label %out
323 a_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
329 next:
330 ; CHECK: next:
331 ; CHECK: ret i1 false
332   ret i1 %res
333 out:
334   ret i1 false
337 define i1 @clamp_low2(i32 %a) {
338 ; CHECK-LABEL: @clamp_low2(
339 entry:
340   %cmp = icmp sge i32 %a, 5
341   br i1 %cmp, label %a_guard, label %out
343 a_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
349 next:
350 ; CHECK: next:
351 ; CHECK: ret i1 false
352   ret i1 %res
353 out:
354   ret i1 false
357 define i1 @clamp_high1(i32 %a) {
358 ; CHECK-LABEL: @clamp_high1(
359 entry:
360   %cmp = icmp sle i32 %a, 5
361   br i1 %cmp, label %a_guard, label %out
363 a_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
369 next:
370 ; CHECK: next:
371 ; CHECK: ret i1 false
372   ret i1 %res
373 out:
374   ret i1 false
377 define i1 @clamp_high2(i32 %a) {
378 ; CHECK-LABEL: @clamp_high2(
379 entry:
380   %cmp = icmp sle i32 %a, 5
381   br i1 %cmp, label %a_guard, label %out
383 a_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
389 next:
390 ; CHECK: next:
391 ; CHECK: ret i1 false
392   ret i1 %res
393 out:
394   ret i1 false
397 ; Just showing arbitrary constants work, not really a clamp
398 define i1 @clamp_high3(i32 %a) {
399 ; CHECK-LABEL: @clamp_high3(
400 entry:
401   %cmp = icmp sle i32 %a, 5
402   br i1 %cmp, label %a_guard, label %out
404 a_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
410 next:
411 ; CHECK: next:
412 ; CHECK: ret i1 false
413   ret i1 %res
414 out:
415   ret i1 false
418 define i1 @zext_unknown(i8 %a) {
419 ; CHECK-LABEL: @zext_unknown
420 ; CHECK: ret i1 true
421 entry:
422   %a32 = zext i8 %a to i32
423   %cmp = icmp sle i32 %a32, 256
424   br label %exit
425 exit:
426   ret i1 %cmp
429 define i1 @trunc_unknown(i32 %a) {
430 ; CHECK-LABEL: @trunc_unknown
431 ; CHECK: ret i1 true
432 entry:
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
437 exit:
438   ret i1 %cmp
441 ; TODO: missed optimization
442 ; Make sure we exercise non-integer inputs to unary operators (i.e. crash 
443 ; check).
444 define i1 @bitcast_unknown(float %a) {
445 ; CHECK-LABEL: @bitcast_unknown
446 ; CHECK: ret i1 %cmp
447 entry:
448   %a32 = bitcast float %a to i32
449   %cmp = icmp sle i32 %a32, 128
450   br label %exit
451 exit:
452   ret i1 %cmp
455 define i1 @bitcast_unknown2(i8* %p) {
456 ; CHECK-LABEL: @bitcast_unknown2
457 ; CHECK: ret i1 %cmp
458 entry:
459   %p64 = ptrtoint i8* %p to i64
460   %cmp = icmp sle i64 %p64, 128
461   br label %exit
462 exit:
463   ret i1 %cmp
467 define i1 @and_unknown(i32 %a) {
468 ; CHECK-LABEL: @and_unknown
469 ; CHECK: ret i1 true
470 entry:
471   %and = and i32 %a, 128
472   %cmp = icmp sle i32 %and, 128
473   br label %exit
474 exit:
475   ret i1 %cmp
478 define i1 @lshr_unknown(i32 %a) {
479 ; CHECK-LABEL: @lshr_unknown
480 ; CHECK: ret i1 true
481 entry:
482   %and = lshr i32 %a, 30
483   %cmp = icmp sle i32 %and, 128
484   br label %exit
485 exit:
486   ret i1 %cmp