Home | History | Annotate | Download | only in InstCombine
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; This test case tests the InstructionCombining optimization that
      3 ; reduces things like:
      4 ;   %Y = sext i8 %X to i32
      5 ;   %C = icmp ult i32 %Y, 1024
      6 ; to
      7 ;   %C = i1 true
      8 ; It includes test cases for different constant values, signedness of the
      9 ; cast operands, and types of setCC operators. In all cases, the cast should
     10 ; be eliminated. In many cases the setCC is also eliminated based on the
     11 ; constant value and the range of the casted value.
     12 ;
     13 ; RUN: opt < %s -instcombine -S | FileCheck %s
     14 
     15 define i1 @lt_signed_to_large_unsigned(i8 %SB) {
     16 ; CHECK-LABEL: @lt_signed_to_large_unsigned(
     17 ; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i8 %SB, -1
     18 ; CHECK-NEXT:    ret i1 [[C1]]
     19 ;
     20   %Y = sext i8 %SB to i32
     21   %C = icmp ult i32 %Y, 1024
     22   ret i1 %C
     23 }
     24 
     25 ; PR28011 - https://llvm.org/bugs/show_bug.cgi?id=28011
     26 ; The above transform only applies to scalar integers; it shouldn't be attempted for constant expressions or vectors.
     27 
     28 @a = common global i32** null
     29 @b = common global [1 x i32] zeroinitializer
     30 
     31 define i1 @PR28011(i16 %a) {
     32 ; CHECK-LABEL: @PR28011(
     33 ; CHECK-NEXT:    [[CONV:%.*]] = sext i16 %a to i32
     34 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[CONV]], or (i32 zext (i1 icmp ne (i32*** bitcast ([1 x i32]* @b to i32***), i32*** @a) to i32), i32 1)
     35 ; CHECK-NEXT:    ret i1 [[CMP]]
     36 ;
     37   %conv = sext i16 %a to i32
     38   %cmp = icmp ne i32 %conv, or (i32 zext (i1 icmp ne (i32*** bitcast ([1 x i32]* @b to i32***), i32*** @a) to i32), i32 1)
     39   ret i1 %cmp
     40 }
     41 
     42 define <2 x i1> @lt_signed_to_large_unsigned_vec(<2 x i8> %SB) {
     43 ; CHECK-LABEL: @lt_signed_to_large_unsigned_vec(
     44 ; CHECK-NEXT:    [[Y:%.*]] = sext <2 x i8> %SB to <2 x i32>
     45 ; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i32> [[Y]], <i32 1024, i32 2>
     46 ; CHECK-NEXT:    ret <2 x i1> [[C]]
     47 ;
     48   %Y = sext <2 x i8> %SB to <2 x i32>
     49   %C = icmp ult <2 x i32> %Y, <i32 1024, i32 2>
     50   ret <2 x i1> %C
     51 }
     52 
     53 define i1 @lt_signed_to_large_signed(i8 %SB) {
     54 ; CHECK-LABEL: @lt_signed_to_large_signed(
     55 ; CHECK-NEXT:    ret i1 true
     56 ;
     57   %Y = sext i8 %SB to i32
     58   %C = icmp slt i32 %Y, 1024
     59   ret i1 %C
     60 }
     61 
     62 define i1 @lt_signed_to_large_negative(i8 %SB) {
     63 ; CHECK-LABEL: @lt_signed_to_large_negative(
     64 ; CHECK-NEXT:    ret i1 false
     65 ;
     66   %Y = sext i8 %SB to i32
     67   %C = icmp slt i32 %Y, -1024
     68   ret i1 %C
     69 }
     70 
     71 define i1 @lt_signed_to_small_unsigned(i8 %SB) {
     72 ; CHECK-LABEL: @lt_signed_to_small_unsigned(
     73 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 %SB, 17
     74 ; CHECK-NEXT:    ret i1 [[C]]
     75 ;
     76   %Y = sext i8 %SB to i32
     77   %C = icmp ult i32 %Y, 17
     78   ret i1 %C
     79 }
     80 
     81 define i1 @lt_signed_to_small_signed(i8 %SB) {
     82 ; CHECK-LABEL: @lt_signed_to_small_signed(
     83 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 %SB, 17
     84 ; CHECK-NEXT:    ret i1 [[C]]
     85 ;
     86   %Y = sext i8 %SB to i32
     87   %C = icmp slt i32 %Y, 17
     88   ret i1 %C
     89 }
     90 define i1 @lt_signed_to_small_negative(i8 %SB) {
     91 ; CHECK-LABEL: @lt_signed_to_small_negative(
     92 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 %SB, -17
     93 ; CHECK-NEXT:    ret i1 [[C]]
     94 ;
     95   %Y = sext i8 %SB to i32
     96   %C = icmp slt i32 %Y, -17
     97   ret i1 %C
     98 }
     99 
    100 define i1 @lt_unsigned_to_large_unsigned(i8 %SB) {
    101 ; CHECK-LABEL: @lt_unsigned_to_large_unsigned(
    102 ; CHECK-NEXT:    ret i1 true
    103 ;
    104   %Y = zext i8 %SB to i32
    105   %C = icmp ult i32 %Y, 1024
    106   ret i1 %C
    107 }
    108 
    109 define i1 @lt_unsigned_to_large_signed(i8 %SB) {
    110 ; CHECK-LABEL: @lt_unsigned_to_large_signed(
    111 ; CHECK-NEXT:    ret i1 true
    112 ;
    113   %Y = zext i8 %SB to i32
    114   %C = icmp slt i32 %Y, 1024
    115   ret i1 %C
    116 }
    117 
    118 define i1 @lt_unsigned_to_large_negative(i8 %SB) {
    119 ; CHECK-LABEL: @lt_unsigned_to_large_negative(
    120 ; CHECK-NEXT:    ret i1 false
    121 ;
    122   %Y = zext i8 %SB to i32
    123   %C = icmp slt i32 %Y, -1024
    124   ret i1 %C
    125 }
    126 
    127 define i1 @lt_unsigned_to_small_unsigned(i8 %SB) {
    128 ; CHECK-LABEL: @lt_unsigned_to_small_unsigned(
    129 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 %SB, 17
    130 ; CHECK-NEXT:    ret i1 [[C]]
    131 ;
    132   %Y = zext i8 %SB to i32
    133   %C = icmp ult i32 %Y, 17
    134   ret i1 %C
    135 }
    136 
    137 define i1 @lt_unsigned_to_small_signed(i8 %SB) {
    138 ; CHECK-LABEL: @lt_unsigned_to_small_signed(
    139 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 %SB, 17
    140 ; CHECK-NEXT:    ret i1 [[C]]
    141 ;
    142   %Y = zext i8 %SB to i32
    143   %C = icmp slt i32 %Y, 17
    144   ret i1 %C
    145 }
    146 
    147 define i1 @lt_unsigned_to_small_negative(i8 %SB) {
    148 ; CHECK-LABEL: @lt_unsigned_to_small_negative(
    149 ; CHECK-NEXT:    ret i1 false
    150 ;
    151   %Y = zext i8 %SB to i32
    152   %C = icmp slt i32 %Y, -17
    153   ret i1 %C
    154 }
    155 
    156 define i1 @gt_signed_to_large_unsigned(i8 %SB) {
    157 ; CHECK-LABEL: @gt_signed_to_large_unsigned(
    158 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 %SB, 0
    159 ; CHECK-NEXT:    ret i1 [[C]]
    160 ;
    161   %Y = sext i8 %SB to i32
    162   %C = icmp ugt i32 %Y, 1024
    163   ret i1 %C
    164 }
    165 
    166 define i1 @gt_signed_to_large_signed(i8 %SB) {
    167 ; CHECK-LABEL: @gt_signed_to_large_signed(
    168 ; CHECK-NEXT:    ret i1 false
    169 ;
    170   %Y = sext i8 %SB to i32
    171   %C = icmp sgt i32 %Y, 1024
    172   ret i1 %C
    173 }
    174 
    175 define i1 @gt_signed_to_large_negative(i8 %SB) {
    176 ; CHECK-LABEL: @gt_signed_to_large_negative(
    177 ; CHECK-NEXT:    ret i1 true
    178 ;
    179   %Y = sext i8 %SB to i32
    180   %C = icmp sgt i32 %Y, -1024
    181   ret i1 %C
    182 }
    183 
    184 define i1 @gt_signed_to_small_unsigned(i8 %SB) {
    185 ; CHECK-LABEL: @gt_signed_to_small_unsigned(
    186 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 %SB, 17
    187 ; CHECK-NEXT:    ret i1 [[C]]
    188 ;
    189   %Y = sext i8 %SB to i32
    190   %C = icmp ugt i32 %Y, 17
    191   ret i1 %C
    192 }
    193 
    194 define i1 @gt_signed_to_small_signed(i8 %SB) {
    195 ; CHECK-LABEL: @gt_signed_to_small_signed(
    196 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 %SB, 17
    197 ; CHECK-NEXT:    ret i1 [[C]]
    198 ;
    199   %Y = sext i8 %SB to i32
    200   %C = icmp sgt i32 %Y, 17
    201   ret i1 %C
    202 }
    203 
    204 define i1 @gt_signed_to_small_negative(i8 %SB) {
    205 ; CHECK-LABEL: @gt_signed_to_small_negative(
    206 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 %SB, -17
    207 ; CHECK-NEXT:    ret i1 [[C]]
    208 ;
    209   %Y = sext i8 %SB to i32
    210   %C = icmp sgt i32 %Y, -17
    211   ret i1 %C
    212 }
    213 
    214 define i1 @gt_unsigned_to_large_unsigned(i8 %SB) {
    215 ; CHECK-LABEL: @gt_unsigned_to_large_unsigned(
    216 ; CHECK-NEXT:    ret i1 false
    217 ;
    218   %Y = zext i8 %SB to i32
    219   %C = icmp ugt i32 %Y, 1024
    220   ret i1 %C
    221 }
    222 
    223 define i1 @gt_unsigned_to_large_signed(i8 %SB) {
    224 ; CHECK-LABEL: @gt_unsigned_to_large_signed(
    225 ; CHECK-NEXT:    ret i1 false
    226 ;
    227   %Y = zext i8 %SB to i32
    228   %C = icmp sgt i32 %Y, 1024
    229   ret i1 %C
    230 }
    231 
    232 define i1 @gt_unsigned_to_large_negative(i8 %SB) {
    233 ; CHECK-LABEL: @gt_unsigned_to_large_negative(
    234 ; CHECK-NEXT:    ret i1 true
    235 ;
    236   %Y = zext i8 %SB to i32
    237   %C = icmp sgt i32 %Y, -1024
    238   ret i1 %C
    239 }
    240 
    241 define i1 @gt_unsigned_to_small_unsigned(i8 %SB) {
    242 ; CHECK-LABEL: @gt_unsigned_to_small_unsigned(
    243 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 %SB, 17
    244 ; CHECK-NEXT:    ret i1 [[C]]
    245 ;
    246   %Y = zext i8 %SB to i32
    247   %C = icmp ugt i32 %Y, 17
    248   ret i1 %C
    249 }
    250 
    251 define i1 @gt_unsigned_to_small_signed(i8 %SB) {
    252 ; CHECK-LABEL: @gt_unsigned_to_small_signed(
    253 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 %SB, 17
    254 ; CHECK-NEXT:    ret i1 [[C]]
    255 ;
    256   %Y = zext i8 %SB to i32
    257   %C = icmp sgt i32 %Y, 17
    258   ret i1 %C
    259 }
    260 
    261 define i1 @gt_unsigned_to_small_negative(i8 %SB) {
    262 ; CHECK-LABEL: @gt_unsigned_to_small_negative(
    263 ; CHECK-NEXT:    ret i1 true
    264 ;
    265   %Y = zext i8 %SB to i32
    266   %C = icmp sgt i32 %Y, -17
    267   ret i1 %C
    268 }
    269 
    270