1 ; RUN: opt < %s -correlated-propagation -S | FileCheck %s
5 define i32 @test1(i1 %C) nounwind {
6 br i1 %C, label %exit, label %body
10 %A = select i1 %C, i32 10, i32 11 ; <i32> [#uses=1]
21 ; CHECK-LABEL: @test2(
24 %cond = tail call i1 @ext() ; <i1> [#uses=2]
25 br i1 %cond, label %bb1, label %bb2
28 %cond2 = tail call i1 @ext() ; <i1> [#uses=1]
29 br i1 %cond2, label %bb3, label %bb2
31 bb2: ; preds = %bb1, %entry
33 %cond_merge = phi i1 [ %cond, %entry ], [ false, %bb1 ] ; <i1> [#uses=1]
38 %res = tail call i1 @ext() ; <i1> [#uses=1]
44 @gv = internal constant i8 7
45 ; CHECK-LABEL: @test3(
46 define i8 @test3(i8* %a) nounwind {
48 %cond = icmp eq i8* %a, @gv
49 br i1 %cond, label %bb2, label %bb
55 ; CHECK: %should_be_const = load i8, i8* @gv
56 %should_be_const = load i8, i8* %a
57 ret i8 %should_be_const
61 ; CHECK-LABEL: @test4(
62 define i32 @test4(i32) {
64 ; CHECK: icmp sgt i32 %0, 2
65 %.demorgan = icmp sgt i32 %0, 2
66 br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo
69 ; CHECK-NOT: icmp eq i32 %0, 2
72 br i1 %1, label %Impossible, label %NotTwoAndGreaterThanTwo
74 NotTwoAndGreaterThanTwo:
85 define void @test5(i32* %x, i32* %y) {
86 ; CHECK-LABEL: @test5(
88 %pre = icmp eq i32* %x, null
89 br i1 %pre, label %return, label %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
104 define i32 @switch1(i32 %s) {
105 ; CHECK-LABEL: @switch1(
107 %cmp = icmp slt i32 %s, 0
108 br i1 %cmp, label %negative, label %out
111 switch i32 %s, label %out [
112 ; CHECK: switch i32 %s, label %out
118 ; CHECK-DAG: i32 -1, label %next
120 ; CHECK-DAG: i32 -2, label %next
128 %p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ]
132 %q = phi i32 [ 0, %negative ], [ 0, %negative ]
136 define i32 @switch2(i32 %s) {
137 ; CHECK-LABEL: @switch2(
139 %cmp = icmp sgt i32 %s, 0
140 br i1 %cmp, label %positive, label %out
143 switch i32 %s, label %out [
148 ; CHECK: br label %out
151 %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
155 %q = phi i32 [ 0, %positive ], [ 0, %positive ]
159 define i32 @switch3(i32 %s) {
160 ; CHECK-LABEL: @switch3(
162 %cmp = icmp sgt i32 %s, 0
163 br i1 %cmp, label %positive, label %out
166 switch i32 %s, label %out [
171 ; CHECK: br label %out
174 %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
178 %q = phi i32 [ 0, %positive ], [ 0, %positive ]
182 define void @switch4(i32 %s) {
183 ; CHECK-LABEL: @switch4(
185 %cmp = icmp eq i32 %s, 0
186 br i1 %cmp, label %zero, label %out
189 switch i32 %s, label %out [
194 ; CHECK: br label %next
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
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
225 define i1 @umin(i32 %a, i32 %b) {
226 ; CHECK-LABEL: @umin(
228 %cmp = icmp ult i32 %a, 5
229 br i1 %cmp, label %a_guard, label %out
232 %cmp2 = icmp ult i32 %b, 20
233 br i1 %cmp2, label %b_guard, label %out
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
242 ; CHECK: ret i1 false
248 define i1 @smin(i32 %a, i32 %b) {
249 ; CHECK-LABEL: @smin(
251 %cmp = icmp ult i32 %a, 5
252 br i1 %cmp, label %a_guard, label %out
255 %cmp2 = icmp ult i32 %b, 20
256 br i1 %cmp2, label %b_guard, label %out
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
265 ; CHECK: ret i1 false
271 define i1 @smax(i32 %a, i32 %b) {
272 ; CHECK-LABEL: @smax(
274 %cmp = icmp sgt i32 %a, 5
275 br i1 %cmp, label %a_guard, label %out
278 %cmp2 = icmp sgt i32 %b, 20
279 br i1 %cmp2, label %b_guard, label %out
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
288 ; CHECK: ret i1 false
294 define i1 @umax(i32 %a, i32 %b) {
295 ; CHECK-LABEL: @umax(
297 %cmp = icmp sgt i32 %a, 5
298 br i1 %cmp, label %a_guard, label %out
301 %cmp2 = icmp sgt i32 %b, 20
302 br i1 %cmp2, label %b_guard, label %out
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
311 ; CHECK: ret i1 false
317 define i1 @clamp_low1(i32 %a) {
318 ; CHECK-LABEL: @clamp_low1(
320 %cmp = icmp sge i32 %a, 5
321 br i1 %cmp, label %a_guard, label %out
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
331 ; CHECK: ret i1 false
337 define i1 @clamp_low2(i32 %a) {
338 ; CHECK-LABEL: @clamp_low2(
340 %cmp = icmp sge i32 %a, 5
341 br i1 %cmp, label %a_guard, label %out
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
351 ; CHECK: ret i1 false
357 define i1 @clamp_high1(i32 %a) {
358 ; CHECK-LABEL: @clamp_high1(
360 %cmp = icmp sle i32 %a, 5
361 br i1 %cmp, label %a_guard, label %out
364 %sel_cmp = icmp eq i32 %a, 5
366 %sel = select i1 %sel_cmp, i32 5, i32 %a
367 %res = icmp eq i32 %sel, 6
371 ; CHECK: ret i1 false
377 define i1 @clamp_high2(i32 %a) {
378 ; CHECK-LABEL: @clamp_high2(
380 %cmp = icmp sle i32 %a, 5
381 br i1 %cmp, label %a_guard, label %out
384 %sel_cmp = icmp ne i32 %a, 5
386 %sel = select i1 %sel_cmp, i32 %a, i32 5
387 %res = icmp eq i32 %sel, 6
391 ; CHECK: 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(
401 %cmp = icmp sle i32 %a, 5
402 br i1 %cmp, label %a_guard, label %out
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
412 ; CHECK: ret i1 false
418 define i1 @zext_unknown(i8 %a) {
419 ; CHECK-LABEL: @zext_unknown
422 %a32 = zext i8 %a to i32
423 %cmp = icmp sle i32 %a32, 256
429 define i1 @trunc_unknown(i32 %a) {
430 ; CHECK-LABEL: @trunc_unknown
433 %a8 = trunc i32 %a to i8
434 %a32 = sext i8 %a8 to i32
435 %cmp = icmp sle i32 %a32, 128
441 ; TODO: missed optimization
442 ; Make sure we exercise non-integer inputs to unary operators (i.e. crash
444 define i1 @bitcast_unknown(float %a) {
445 ; CHECK-LABEL: @bitcast_unknown
448 %a32 = bitcast float %a to i32
449 %cmp = icmp sle i32 %a32, 128
455 define i1 @bitcast_unknown2(i8* %p) {
456 ; CHECK-LABEL: @bitcast_unknown2
459 %p64 = ptrtoint i8* %p to i64
460 %cmp = icmp sle i64 %p64, 128
467 define i1 @and_unknown(i32 %a) {
468 ; CHECK-LABEL: @and_unknown
471 %and = and i32 %a, 128
472 %cmp = icmp sle i32 %and, 128
478 define i1 @lshr_unknown(i32 %a) {
479 ; CHECK-LABEL: @lshr_unknown
482 %and = lshr i32 %a, 30
483 %cmp = icmp sle i32 %and, 128