Home | History | Annotate | Download | only in InstCombine
      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