| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s |
| |
| declare void @llvm.assume(i1) |
| declare i8 @llvm.umin(i8, i8) |
| declare i8 @llvm.umax(i8, i8) |
| declare i8 @llvm.smin(i8, i8) |
| declare i8 @llvm.smax(i8, i8) |
| |
| ; If we don't know anything about the arguments, we can't do anything. |
| |
| define i8 @test0(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @test0( |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %r = call i8 @llvm.umin(i8 %x, i8 %y) |
| ret i8 %r |
| } |
| define i8 @test1(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @test1( |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %r = call i8 @llvm.umax(i8 %x, i8 %y) |
| ret i8 %r |
| } |
| define i8 @test2(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @test2( |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %r = call i8 @llvm.smin(i8 %x, i8 %y) |
| ret i8 %r |
| } |
| define i8 @test3(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @test3( |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %r = call i8 @llvm.smax(i8 %x, i8 %y) |
| ret i8 %r |
| } |
| |
| ; However, if we do know the ranges of arguments, we sometimes can tell that either one is always picked. |
| |
| define i8 @test4(i8 %x) { |
| ; CHECK-LABEL: @test4( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 43 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42) |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lim = icmp ule i8 %x, 43 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.umin(i8 %x, i8 42) |
| ret i8 %r |
| } |
| define i8 @test5(i8 %x) { |
| ; CHECK-LABEL: @test5( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: ret i8 [[X]] |
| ; |
| %lim = icmp ule i8 %x, 42 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.umin(i8 %x, i8 42) |
| ret i8 %r |
| } |
| define i8 @test6(i8 %x) { |
| ; CHECK-LABEL: @test6( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42) |
| ; CHECK-NEXT: ret i8 42 |
| ; |
| %lim = icmp uge i8 %x, 42 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.umin(i8 %x, i8 42) |
| ret i8 %r |
| } |
| define i8 @test7(i8 %x) { |
| ; CHECK-LABEL: @test7( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 41 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42) |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lim = icmp uge i8 %x, 41 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.umin(i8 %x, i8 42) |
| ret i8 %r |
| } |
| |
| define i8 @test8(i8 %x) { |
| ; CHECK-LABEL: @test8( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 41 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 42) |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lim = icmp uge i8 %x, 41 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.umax(i8 %x, i8 42) |
| ret i8 %r |
| } |
| define i8 @test9(i8 %x) { |
| ; CHECK-LABEL: @test9( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: ret i8 [[X]] |
| ; |
| %lim = icmp uge i8 %x, 42 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.umax(i8 %x, i8 42) |
| ret i8 %r |
| } |
| define i8 @test10(i8 %x) { |
| ; CHECK-LABEL: @test10( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 42) |
| ; CHECK-NEXT: ret i8 42 |
| ; |
| %lim = icmp ule i8 %x, 42 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.umax(i8 %x, i8 42) |
| ret i8 %r |
| } |
| define i8 @test11(i8 %x) { |
| ; CHECK-LABEL: @test11( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 43 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 42) |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lim = icmp ule i8 %x, 43 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.umax(i8 %x, i8 42) |
| ret i8 %r |
| } |
| |
| define i8 @test12(i8 %x) { |
| ; CHECK-LABEL: @test12( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 43 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 42) |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lim = icmp sle i8 %x, 43 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.smin(i8 %x, i8 42) |
| ret i8 %r |
| } |
| define i8 @test13(i8 %x) { |
| ; CHECK-LABEL: @test13( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: ret i8 [[X]] |
| ; |
| %lim = icmp sle i8 %x, 42 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.smin(i8 %x, i8 42) |
| ret i8 %r |
| } |
| define i8 @test14(i8 %x) { |
| ; CHECK-LABEL: @test14( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 42) |
| ; CHECK-NEXT: ret i8 42 |
| ; |
| %lim = icmp sge i8 %x, 42 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.smin(i8 %x, i8 42) |
| ret i8 %r |
| } |
| define i8 @test15(i8 %x) { |
| ; CHECK-LABEL: @test15( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 41 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 42) |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lim = icmp sge i8 %x, 41 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.smin(i8 %x, i8 42) |
| ret i8 %r |
| } |
| |
| define i8 @test16(i8 %x) { |
| ; CHECK-LABEL: @test16( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 41 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 42) |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lim = icmp sge i8 %x, 41 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.smax(i8 %x, i8 42) |
| ret i8 %r |
| } |
| define i8 @test17(i8 %x) { |
| ; CHECK-LABEL: @test17( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: ret i8 [[X]] |
| ; |
| %lim = icmp sge i8 %x, 42 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.smax(i8 %x, i8 42) |
| ret i8 %r |
| } |
| define i8 @test18(i8 %x) { |
| ; CHECK-LABEL: @test18( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 42) |
| ; CHECK-NEXT: ret i8 42 |
| ; |
| %lim = icmp sle i8 %x, 42 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.smax(i8 %x, i8 42) |
| ret i8 %r |
| } |
| define i8 @test19(i8 %x) { |
| ; CHECK-LABEL: @test19( |
| ; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 43 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 42) |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lim = icmp sle i8 %x, 43 |
| call void @llvm.assume(i1 %lim) |
| %r = call i8 @llvm.smax(i8 %x, i8 42) |
| ret i8 %r |
| } |