Home | History | Annotate | Download | only in InstCombine
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; RUN: opt -S -instcombine < %s | FileCheck %s
      3 
      4 ; If we have a umin feeding an unsigned or equality icmp that shares an
      5 ; operand with the umin, the compare should always be folded.
      6 ; Test all 4 foldable predicates (eq,ne,uge,ult) * 4 commutation
      7 ; possibilities for each predicate. Note that folds to true/false
      8 ; (predicate is ule/ugt) or folds to an existing instruction should be
      9 ; handled by InstSimplify.
     10 
     11 ; umin(X, Y) == X --> X <= Y
     12 
     13 define i1 @eq_umin1(i32 %x, i32 %y) {
     14 ; CHECK-LABEL: @eq_umin1(
     15 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 %x, %y
     16 ; CHECK-NEXT:    ret i1 [[CMP2]]
     17 ;
     18   %cmp1 = icmp ult i32 %x, %y
     19   %sel = select i1 %cmp1, i32 %x, i32 %y
     20   %cmp2 = icmp eq i32 %sel, %x
     21   ret i1 %cmp2
     22 }
     23 
     24 ; Commute min operands.
     25 
     26 define i1 @eq_umin2(i32 %x, i32 %y) {
     27 ; CHECK-LABEL: @eq_umin2(
     28 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 %x, %y
     29 ; CHECK-NEXT:    ret i1 [[CMP2]]
     30 ;
     31   %cmp1 = icmp ult i32 %y, %x
     32   %sel = select i1 %cmp1, i32 %y, i32 %x
     33   %cmp2 = icmp eq i32 %sel, %x
     34   ret i1 %cmp2
     35 }
     36 
     37 ; Disguise the icmp predicate by commuting the min op to the RHS.
     38 
     39 define i1 @eq_umin3(i32 %a, i32 %y) {
     40 ; CHECK-LABEL: @eq_umin3(
     41 ; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
     42 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[X]], %y
     43 ; CHECK-NEXT:    ret i1 [[CMP2]]
     44 ;
     45   %x = add i32 %a, 3 ; thwart complexity-based canonicalization
     46   %cmp1 = icmp ult i32 %x, %y
     47   %sel = select i1 %cmp1, i32 %x, i32 %y
     48   %cmp2 = icmp eq i32 %x, %sel
     49   ret i1 %cmp2
     50 }
     51 
     52 ; Commute min operands.
     53 
     54 define i1 @eq_umin4(i32 %a, i32 %y) {
     55 ; CHECK-LABEL: @eq_umin4(
     56 ; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
     57 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[X]], %y
     58 ; CHECK-NEXT:    ret i1 [[CMP2]]
     59 ;
     60   %x = add i32 %a, 3 ; thwart complexity-based canonicalization
     61   %cmp1 = icmp ult i32 %y, %x
     62   %sel = select i1 %cmp1, i32 %y, i32 %x
     63   %cmp2 = icmp eq i32 %x, %sel
     64   ret i1 %cmp2
     65 }
     66 
     67 ; umin(X, Y) >= X --> X <= Y
     68 
     69 define i1 @uge_umin1(i32 %x, i32 %y) {
     70 ; CHECK-LABEL: @uge_umin1(
     71 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 %x, %y
     72 ; CHECK-NEXT:    ret i1 [[CMP2]]
     73 ;
     74   %cmp1 = icmp ult i32 %x, %y
     75   %sel = select i1 %cmp1, i32 %x, i32 %y
     76   %cmp2 = icmp uge i32 %sel, %x
     77   ret i1 %cmp2
     78 }
     79 
     80 ; Commute min operands.
     81 
     82 define i1 @uge_umin2(i32 %x, i32 %y) {
     83 ; CHECK-LABEL: @uge_umin2(
     84 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 %x, %y
     85 ; CHECK-NEXT:    ret i1 [[CMP2]]
     86 ;
     87   %cmp1 = icmp ult i32 %y, %x
     88   %sel = select i1 %cmp1, i32 %y, i32 %x
     89   %cmp2 = icmp uge i32 %sel, %x
     90   ret i1 %cmp2
     91 }
     92 
     93 ; Disguise the icmp predicate by commuting the min op to the RHS.
     94 
     95 define i1 @uge_umin3(i32 %a, i32 %y) {
     96 ; CHECK-LABEL: @uge_umin3(
     97 ; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
     98 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[X]], %y
     99 ; CHECK-NEXT:    ret i1 [[CMP2]]
    100 ;
    101   %x = add i32 %a, 3 ; thwart complexity-based canonicalization
    102   %cmp1 = icmp ult i32 %x, %y
    103   %sel = select i1 %cmp1, i32 %x, i32 %y
    104   %cmp2 = icmp ule i32 %x, %sel
    105   ret i1 %cmp2
    106 }
    107 
    108 ; Commute min operands.
    109 
    110 define i1 @uge_umin4(i32 %a, i32 %y) {
    111 ; CHECK-LABEL: @uge_umin4(
    112 ; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
    113 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[X]], %y
    114 ; CHECK-NEXT:    ret i1 [[CMP2]]
    115 ;
    116   %x = add i32 %a, 3 ; thwart complexity-based canonicalization
    117   %cmp1 = icmp ult i32 %y, %x
    118   %sel = select i1 %cmp1, i32 %y, i32 %x
    119   %cmp2 = icmp ule i32 %x, %sel
    120   ret i1 %cmp2
    121 }
    122 
    123 ; umin(X, Y) != X --> X > Y
    124 
    125 define i1 @ne_umin1(i32 %x, i32 %y) {
    126 ; CHECK-LABEL: @ne_umin1(
    127 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 %x, %y
    128 ; CHECK-NEXT:    ret i1 [[CMP2]]
    129 ;
    130   %cmp1 = icmp ult i32 %x, %y
    131   %sel = select i1 %cmp1, i32 %x, i32 %y
    132   %cmp2 = icmp ne i32 %sel, %x
    133   ret i1 %cmp2
    134 }
    135 
    136 ; Commute min operands.
    137 
    138 define i1 @ne_umin2(i32 %x, i32 %y) {
    139 ; CHECK-LABEL: @ne_umin2(
    140 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 %y, %x
    141 ; CHECK-NEXT:    ret i1 [[CMP1]]
    142 ;
    143   %cmp1 = icmp ult i32 %y, %x
    144   %sel = select i1 %cmp1, i32 %y, i32 %x
    145   %cmp2 = icmp ne i32 %sel, %x
    146   ret i1 %cmp2
    147 }
    148 
    149 ; Disguise the icmp predicate by commuting the min op to the RHS.
    150 
    151 define i1 @ne_umin3(i32 %a, i32 %y) {
    152 ; CHECK-LABEL: @ne_umin3(
    153 ; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
    154 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[X]], %y
    155 ; CHECK-NEXT:    ret i1 [[CMP2]]
    156 ;
    157   %x = add i32 %a, 3 ; thwart complexity-based canonicalization
    158   %cmp1 = icmp ult i32 %x, %y
    159   %sel = select i1 %cmp1, i32 %x, i32 %y
    160   %cmp2 = icmp ne i32 %x, %sel
    161   ret i1 %cmp2
    162 }
    163 
    164 ; Commute min operands.
    165 
    166 define i1 @ne_umin4(i32 %a, i32 %y) {
    167 ; CHECK-LABEL: @ne_umin4(
    168 ; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
    169 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i32 [[X]], %y
    170 ; CHECK-NEXT:    ret i1 [[CMP1]]
    171 ;
    172   %x = add i32 %a, 3 ; thwart complexity-based canonicalization
    173   %cmp1 = icmp ult i32 %y, %x
    174   %sel = select i1 %cmp1, i32 %y, i32 %x
    175   %cmp2 = icmp ne i32 %x, %sel
    176   ret i1 %cmp2
    177 }
    178 
    179 ; umin(X, Y) < X --> X > Y
    180 
    181 define i1 @ult_umin1(i32 %x, i32 %y) {
    182 ; CHECK-LABEL: @ult_umin1(
    183 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 %x, %y
    184 ; CHECK-NEXT:    ret i1 [[CMP2]]
    185 ;
    186   %cmp1 = icmp ult i32 %x, %y
    187   %sel = select i1 %cmp1, i32 %x, i32 %y
    188   %cmp2 = icmp ult i32 %sel, %x
    189   ret i1 %cmp2
    190 }
    191 
    192 ; Commute min operands.
    193 
    194 define i1 @ult_umin2(i32 %x, i32 %y) {
    195 ; CHECK-LABEL: @ult_umin2(
    196 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 %y, %x
    197 ; CHECK-NEXT:    ret i1 [[CMP1]]
    198 ;
    199   %cmp1 = icmp ult i32 %y, %x
    200   %sel = select i1 %cmp1, i32 %y, i32 %x
    201   %cmp2 = icmp ult i32 %sel, %x
    202   ret i1 %cmp2
    203 }
    204 
    205 ; Disguise the icmp predicate by commuting the min op to the RHS.
    206 
    207 define i1 @ult_umin3(i32 %a, i32 %y) {
    208 ; CHECK-LABEL: @ult_umin3(
    209 ; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
    210 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[X]], %y
    211 ; CHECK-NEXT:    ret i1 [[CMP2]]
    212 ;
    213   %x = add i32 %a, 3 ; thwart complexity-based canonicalization
    214   %cmp1 = icmp ult i32 %x, %y
    215   %sel = select i1 %cmp1, i32 %x, i32 %y
    216   %cmp2 = icmp ugt i32 %x, %sel
    217   ret i1 %cmp2
    218 }
    219 
    220 ; Commute min operands.
    221 
    222 define i1 @ult_umin4(i32 %a, i32 %y) {
    223 ; CHECK-LABEL: @ult_umin4(
    224 ; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
    225 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i32 [[X]], %y
    226 ; CHECK-NEXT:    ret i1 [[CMP1]]
    227 ;
    228   %x = add i32 %a, 3 ; thwart complexity-based canonicalization
    229   %cmp1 = icmp ult i32 %y, %x
    230   %sel = select i1 %cmp1, i32 %y, i32 %x
    231   %cmp2 = icmp ugt i32 %x, %sel
    232   ret i1 %cmp2
    233 }
    234 
    235