1 ; RUN: opt < %s -instcombine -S | FileCheck %s 2 3 ; A == B implies A >u B is false. 4 ; CHECK-LABEL: @test1 5 ; CHECK-NOT: select 6 ; CHECK: call void @foo(i32 10) 7 define void @test1(i32 %a, i32 %b) { 8 %cmp1 = icmp eq i32 %a, %b 9 br i1 %cmp1, label %taken, label %end 10 11 taken: 12 %cmp2 = icmp ugt i32 %a, %b 13 %c = select i1 %cmp2, i32 0, i32 10 14 call void @foo(i32 %c) 15 br label %end 16 17 end: 18 ret void 19 } 20 21 ; If A == B is false then A != B is true. 22 ; CHECK-LABEL: @test2 23 ; CHECK-NOT: select 24 ; CHECK: call void @foo(i32 20) 25 define void @test2(i32 %a, i32 %b) { 26 %cmp1 = icmp eq i32 %a, %b 27 br i1 %cmp1, label %end, label %taken 28 29 taken: 30 %cmp2 = icmp ne i32 %a, %b 31 %c = select i1 %cmp2, i32 20, i32 0 32 call void @foo(i32 %c) 33 br label %end 34 35 end: 36 ret void 37 } 38 39 ; A >u 10 implies A >u 10 is true. 40 ; CHECK-LABEL: @test3 41 ; CHECK-NOT: select 42 ; CHECK: call void @foo(i32 30) 43 define void @test3(i32 %a) { 44 %cmp1 = icmp ugt i32 %a, 10 45 br i1 %cmp1, label %taken, label %end 46 47 taken: 48 %cmp2 = icmp ugt i32 %a, 10 49 %c = select i1 %cmp2, i32 30, i32 0 50 call void @foo(i32 %c) 51 br label %end 52 53 end: 54 ret void 55 } 56 57 ; CHECK-LABEL: @PR23333 58 ; CHECK-NOT: select 59 ; CHECK: ret i8 1 60 define i8 @PR23333(i8 addrspace(1)* %ptr) { 61 %cmp = icmp eq i8 addrspace(1)* %ptr, null 62 br i1 %cmp, label %taken, label %end 63 64 taken: 65 %cmp2 = icmp ne i8 addrspace(1)* %ptr, null 66 %res = select i1 %cmp2, i8 2, i8 1 67 ret i8 %res 68 69 end: 70 ret i8 0 71 } 72 73 ; We know the condition of the select is true based on a dominating condition. 74 ; Therefore, we can replace %cond with %len. However, now the inner icmp is 75 ; always false and can be elided. 76 ; CHECK-LABEL: @test4 77 ; CHECK-NOT: select 78 define void @test4(i32 %len) { 79 entry: 80 %0 = call i32 @bar(i32 %len); 81 %cmp = icmp ult i32 %len, 4 82 br i1 %cmp, label %bb, label %b1 83 bb: 84 %cond = select i1 %cmp, i32 %len, i32 8 85 ; CHECK-NOT: %cmp11 = icmp eq i32 %{{.*}}, 8 86 %cmp11 = icmp eq i32 %cond, 8 87 ; CHECK: br i1 false, label %b0, label %b1 88 br i1 %cmp11, label %b0, label %b1 89 90 b0: 91 call void @foo(i32 %len) 92 br label %b1 93 94 b1: 95 ; CHECK: phi i32 [ %len, %bb ], [ undef, %b0 ], [ %0, %entry ] 96 %1 = phi i32 [ %cond, %bb ], [ undef, %b0 ], [ %0, %entry ] 97 br label %ret 98 99 ret: 100 call void @foo(i32 %1) 101 ret void 102 } 103 104 ; A >u 10 implies A >u 9 is true. 105 ; CHECK-LABEL: @test5 106 ; CHECK-NOT: select 107 ; CHECK: call void @foo(i32 30) 108 define void @test5(i32 %a) { 109 %cmp1 = icmp ugt i32 %a, 10 110 br i1 %cmp1, label %taken, label %end 111 112 taken: 113 %cmp2 = icmp ugt i32 %a, 9 114 %c = select i1 %cmp2, i32 30, i32 0 115 call void @foo(i32 %c) 116 br label %end 117 118 end: 119 ret void 120 } 121 122 declare void @foo(i32) 123 declare i32 @bar(i32) 124