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) 7define void @test1(i32 %a, i32 %b) { 8 %cmp1 = icmp eq i32 %a, %b 9 br i1 %cmp1, label %taken, label %end 10 11taken: 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 17end: 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) 25define void @test2(i32 %a, i32 %b) { 26 %cmp1 = icmp eq i32 %a, %b 27 br i1 %cmp1, label %end, label %taken 28 29taken: 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 35end: 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) 43define void @test3(i32 %a) { 44 %cmp1 = icmp ugt i32 %a, 10 45 br i1 %cmp1, label %taken, label %end 46 47taken: 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 53end: 54 ret void 55} 56 57; CHECK-LABEL: @PR23333 58; CHECK-NOT: select 59; CHECK: ret i8 1 60define i8 @PR23333(i8 addrspace(1)* %ptr) { 61 %cmp = icmp eq i8 addrspace(1)* %ptr, null 62 br i1 %cmp, label %taken, label %end 63 64taken: 65 %cmp2 = icmp ne i8 addrspace(1)* %ptr, null 66 %res = select i1 %cmp2, i8 2, i8 1 67 ret i8 %res 68 69end: 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 78define void @test4(i32 %len) { 79entry: 80 %0 = call i32 @bar(i32 %len); 81 %cmp = icmp ult i32 %len, 4 82 br i1 %cmp, label %bb, label %b1 83bb: 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 90b0: 91 call void @foo(i32 %len) 92 br label %b1 93 94b1: 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 99ret: 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) 108define void @test5(i32 %a) { 109 %cmp1 = icmp ugt i32 %a, 10 110 br i1 %cmp1, label %taken, label %end 111 112taken: 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 118end: 119 ret void 120} 121 122declare void @foo(i32) 123declare i32 @bar(i32) 124