Home | History | Annotate | Download | only in InstSimplify
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; RUN: opt < %s -instsimplify -S | FileCheck %s
      3 
      4 ; %r = shl nuw i8 C, %x
      5 ; As per langref: If the nuw keyword is present, then the shift produces
      6 ;                 a poison value if it shifts out any non-zero bits.
      7 ; Thus, if the sign bit is set on C, then %x can only be 0, which means that
      8 ; %r can only be C.
      9 
     10 define i8 @shl_nuw (i8 %x) {
     11 ; CHECK-LABEL: @shl_nuw(
     12 ; CHECK-NEXT:    ret i8 -1
     13 ;
     14   %ret = shl nuw i8 -1, %x
     15   ; nuw here means that %x can only be 0
     16   ret i8 %ret
     17 }
     18 
     19 define i8 @shl_nuw_nsw (i8 %x) {
     20 ; CHECK-LABEL: @shl_nuw_nsw(
     21 ; CHECK-NEXT:    ret i8 -1
     22 ;
     23   %ret = shl nuw nsw i8 -1, %x
     24   ; nuw here means that %x can only be 0
     25   ret i8 %ret
     26 }
     27 
     28 define i8 @shl_128 (i8 %x) {
     29 ; CHECK-LABEL: @shl_128(
     30 ; CHECK-NEXT:    ret i8 -128
     31 ;
     32   %ret = shl nuw i8 128, %x
     33   ; 128 == 1<<7 == just the sign bit is set
     34   ret i8 %ret
     35 }
     36 
     37 ; ============================================================================ ;
     38 ; Positive tests with value range known
     39 ; ============================================================================ ;
     40 
     41 declare void @llvm.assume(i1 %cond);
     42 
     43 define i8 @knownbits_negative(i8 %x, i8 %y) {
     44 ; CHECK-LABEL: @knownbits_negative(
     45 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
     46 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
     47 ; CHECK-NEXT:    [[RET:%.*]] = shl nuw i8 [[X]], [[Y:%.*]]
     48 ; CHECK-NEXT:    ret i8 [[RET]]
     49 ;
     50   %cmp = icmp slt i8 %x, 0
     51   tail call void @llvm.assume(i1 %cmp)
     52   %ret = shl nuw i8 %x, %y
     53   ret i8 %ret
     54 }
     55 
     56 define i8 @knownbits_negativeorzero(i8 %x, i8 %y) {
     57 ; CHECK-LABEL: @knownbits_negativeorzero(
     58 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 1
     59 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
     60 ; CHECK-NEXT:    [[RET:%.*]] = shl nuw i8 [[X]], [[Y:%.*]]
     61 ; CHECK-NEXT:    ret i8 [[RET]]
     62 ;
     63   %cmp = icmp slt i8 %x, 1
     64   tail call void @llvm.assume(i1 %cmp)
     65   %ret = shl nuw i8 %x, %y
     66   ret i8 %ret
     67 }
     68 
     69 ; ============================================================================ ;
     70 ; Vectors
     71 ; ============================================================================ ;
     72 
     73 define <2 x i8> @shl_vec(<2 x i8> %x) {
     74 ; CHECK-LABEL: @shl_vec(
     75 ; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
     76 ;
     77   %ret = shl nuw <2 x i8> <i8 -1, i8 -1>, %x
     78   ret <2 x i8> %ret
     79 }
     80 
     81 define <3 x i8> @shl_vec_undef(<3 x i8> %x) {
     82 ; CHECK-LABEL: @shl_vec_undef(
     83 ; CHECK-NEXT:    ret <3 x i8> <i8 -1, i8 undef, i8 -1>
     84 ;
     85   %ret = shl nuw <3 x i8> <i8 -1, i8 undef, i8 -1>, %x
     86   ret <3 x i8> %ret
     87 }
     88 
     89 define <2 x i8> @shl_vec_nonsplat(<2 x i8> %x) {
     90 ; CHECK-LABEL: @shl_vec_nonsplat(
     91 ; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -2>
     92 ;
     93   %ret = shl nuw <2 x i8> <i8 -1, i8 -2>, %x
     94   ret <2 x i8> %ret
     95 }
     96 
     97 ; ============================================================================ ;
     98 ; Negative tests. Should not be folded.
     99 ; ============================================================================ ;
    100 
    101 define i8 @shl_127 (i8 %x) {
    102 ; CHECK-LABEL: @shl_127(
    103 ; CHECK-NEXT:    [[RET:%.*]] = shl nuw i8 127, [[X:%.*]]
    104 ; CHECK-NEXT:    ret i8 [[RET]]
    105 ;
    106   %ret = shl nuw i8 127, %x
    107   ; 127 == (1<<7)-1 == all bits except the sign bit are set.
    108   ret i8 %ret
    109 }
    110 
    111 define i8 @bad_shl (i8 %x) {
    112 ; CHECK-LABEL: @bad_shl(
    113 ; CHECK-NEXT:    [[RET:%.*]] = shl i8 -1, [[X:%.*]]
    114 ; CHECK-NEXT:    ret i8 [[RET]]
    115 ;
    116   %ret = shl i8 -1, %x ; need nuw
    117   ret i8 %ret
    118 }
    119 
    120 define i8 @bad_nsw (i8 %x) {
    121 ; CHECK-LABEL: @bad_nsw(
    122 ; CHECK-NEXT:    [[RET:%.*]] = shl nsw i8 -1, [[X:%.*]]
    123 ; CHECK-NEXT:    ret i8 [[RET]]
    124 ;
    125   %ret = shl nsw i8 -1, %x ; need nuw
    126   ret i8 %ret
    127 }
    128 
    129 ; First `shl` operand is not `-1` constant
    130 
    131 define i8 @bad_shl0(i8 %shlop1, i8 %x) {
    132 ; CHECK-LABEL: @bad_shl0(
    133 ; CHECK-NEXT:    [[RET:%.*]] = shl nuw i8 [[SHLOP1:%.*]], [[X:%.*]]
    134 ; CHECK-NEXT:    ret i8 [[RET]]
    135 ;
    136   %ret = shl nuw i8 %shlop1, %x
    137   ret i8 %ret
    138 }
    139 
    140 ; Bad shl nuw constant
    141 
    142 define i8 @bad_shl1(i8 %x) {
    143 ; CHECK-LABEL: @bad_shl1(
    144 ; CHECK-NEXT:    [[RET:%.*]] = shl nuw i8 1, [[X:%.*]]
    145 ; CHECK-NEXT:    ret i8 [[RET]]
    146 ;
    147   %ret = shl nuw i8 1, %x ; not -1
    148   ret i8 %ret
    149 }
    150 
    151 define <2 x i8> @bad_shl_vec_nonsplat(<2 x i8> %x) {
    152 ; CHECK-LABEL: @bad_shl_vec_nonsplat(
    153 ; CHECK-NEXT:    [[RET:%.*]] = shl nuw <2 x i8> <i8 -1, i8 1>, [[X:%.*]]
    154 ; CHECK-NEXT:    ret <2 x i8> [[RET]]
    155 ;
    156   %ret = shl nuw <2 x i8> <i8 -1, i8 1>, %x
    157   ret <2 x i8> %ret
    158 }
    159 
    160 ; Bad known bits
    161 
    162 define i8 @bad_knownbits(i8 %x, i8 %y) {
    163 ; CHECK-LABEL: @bad_knownbits(
    164 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 2
    165 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
    166 ; CHECK-NEXT:    [[RET:%.*]] = shl nuw i8 [[X]], [[Y:%.*]]
    167 ; CHECK-NEXT:    ret i8 [[RET]]
    168 ;
    169   %cmp = icmp slt i8 %x, 2
    170   tail call void @llvm.assume(i1 %cmp)
    171   %ret = shl nuw i8 %x, %y
    172   ret i8 %ret
    173 }
    174 
    175 define i8 @bad_knownbits_minusoneormore(i8 %x, i8 %y) {
    176 ; CHECK-LABEL: @bad_knownbits_minusoneormore(
    177 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -2
    178 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
    179 ; CHECK-NEXT:    [[RET:%.*]] = shl nuw i8 [[X]], [[Y:%.*]]
    180 ; CHECK-NEXT:    ret i8 [[RET]]
    181 ;
    182   %cmp = icmp sgt i8 %x, -2
    183   tail call void @llvm.assume(i1 %cmp)
    184   %ret = shl nuw i8 %x, %y
    185   ret i8 %ret
    186 }
    187 
    188 define i8 @bad_knownbits_zeroorpositive(i8 %x, i8 %y) {
    189 ; CHECK-LABEL: @bad_knownbits_zeroorpositive(
    190 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
    191 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
    192 ; CHECK-NEXT:    [[RET:%.*]] = shl nuw i8 [[X]], [[Y:%.*]]
    193 ; CHECK-NEXT:    ret i8 [[RET]]
    194 ;
    195   %cmp = icmp sgt i8 %x, -1
    196   tail call void @llvm.assume(i1 %cmp)
    197   %ret = shl nuw i8 %x, %y
    198   ret i8 %ret
    199 }
    200 
    201 define i8 @bad_knownbits_positive(i8 %x, i8 %y) {
    202 ; CHECK-LABEL: @bad_knownbits_positive(
    203 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 0
    204 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
    205 ; CHECK-NEXT:    [[RET:%.*]] = shl nuw i8 [[X]], [[Y:%.*]]
    206 ; CHECK-NEXT:    ret i8 [[RET]]
    207 ;
    208   %cmp = icmp sgt i8 %x, 0
    209   tail call void @llvm.assume(i1 %cmp)
    210   %ret = shl nuw i8 %x, %y
    211   ret i8 %ret
    212 }
    213