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 125; CHECK-LABEL: @test_and 126; CHECK: tpath: 127; CHECK-NOT: select 128; CHECK: ret i32 313 129define i32 @test_and(i32 %a, i32 %b) { 130entry: 131 %cmp1 = icmp ne i32 %a, 0 132 %cmp2 = icmp ne i32 %b, 0 133 %and = and i1 %cmp1, %cmp2 134 br i1 %and, label %tpath, label %end 135 136tpath: 137 %cmp3 = icmp eq i32 %a, 0 ;; <-- implied false 138 %c = select i1 %cmp3, i32 0, i32 313 139 ret i32 %c 140 141end: 142 ret i32 0 143} 144 145; cmp1 and cmp2 are false on the 'fpath' path and thus cmp3 is true. 146; CHECK-LABEL: @test_or1 147; CHECK: fpath: 148; CHECK-NOT: select 149; CHECK: ret i32 37 150define i32 @test_or1(i32 %a, i32 %b) { 151entry: 152 %cmp1 = icmp eq i32 %a, 0 153 %cmp2 = icmp eq i32 %b, 0 154 %or = or i1 %cmp1, %cmp2 155 br i1 %or, label %end, label %fpath 156 157fpath: 158 %cmp3 = icmp ne i32 %a, 0 ;; <-- implied true 159 %c = select i1 %cmp3, i32 37, i32 0 160 ret i32 %c 161 162end: 163 ret i32 0 164} 165 166; LHS ==> RHS by definition (true -> true) 167; CHECK-LABEL: @test6 168; CHECK: taken: 169; CHECK-NOT: select 170; CHECK: call void @foo(i32 10) 171define void @test6(i32 %a, i32 %b) { 172 %cmp1 = icmp eq i32 %a, %b 173 br i1 %cmp1, label %taken, label %end 174 175taken: 176 %c = select i1 %cmp1, i32 10, i32 0 177 call void @foo(i32 %c) 178 br label %end 179 180end: 181 ret void 182} 183 184; LHS ==> RHS by definition (false -> false) 185; CHECK-LABEL: @test7 186; CHECK: taken: 187; CHECK-NOT: select 188; CHECK: call void @foo(i32 11) 189define void @test7(i32 %a, i32 %b) { 190 %cmp1 = icmp eq i32 %a, %b 191 br i1 %cmp1, label %end, label %taken 192 193taken: 194 %c = select i1 %cmp1, i32 0, i32 11 195 call void @foo(i32 %c) 196 br label %end 197 198end: 199 ret void 200} 201