Home | History | Annotate | Download | only in X86
      1 ; RUN: llc -mtriple=x86_64-pc-linux -mattr=mmx < %s | FileCheck %s
      2 
      3 ; MMX packed sub opcodes were wrongly marked as commutative.
      4 ; This test checks that the operands of packed sub instructions are
      5 ; never interchanged by the "Two-Address instruction pass".
      6 
      7 declare { i64, double } @getFirstParam()
      8 declare { i64, double } @getSecondParam()
      9 
     10 define i64 @test_psubb() {
     11 entry:
     12   %call = tail call { i64, double } @getFirstParam()
     13   %0 = extractvalue { i64, double } %call, 0
     14   %call2 = tail call { i64, double } @getSecondParam()
     15   %1 = extractvalue { i64, double } %call2, 0
     16   %__m1.0.insert.i = insertelement <1 x i64> undef, i64 %0, i32 0
     17   %__m2.0.insert.i = insertelement <1 x i64> undef, i64 %1, i32 0
     18   %2 = bitcast <1 x i64> %__m1.0.insert.i to <8 x i8>
     19   %3 = bitcast <8 x i8> %2 to x86_mmx
     20   %4 = bitcast <1 x i64> %__m2.0.insert.i to <8 x i8>
     21   %5 = bitcast <8 x i8> %4 to x86_mmx
     22   %6 = tail call x86_mmx @llvm.x86.mmx.psub.b(x86_mmx %3, x86_mmx %5) nounwind
     23   %7 = bitcast x86_mmx %6 to <8 x i8>
     24   %8 = bitcast <8 x i8> %7 to <1 x i64>
     25   %retval.0.extract.i15 = extractelement <1 x i64> %8, i32 0
     26   ret i64 %retval.0.extract.i15
     27 }
     28 
     29 ; CHECK-LABEL: test_psubb:
     30 ; CHECK:   callq getFirstParam
     31 ; CHECK:   movq %rax, [[TEMP:%[a-z0-9]+]]
     32 ; CHECK:   callq getSecondParam
     33 ; CHECK:   movd [[TEMP]], [[PARAM1:%[a-z0-9]+]]
     34 ; CHECK:   movd %rax, [[PARAM2:%[a-z0-9]+]]
     35 ; CHECK:   psubb [[PARAM2]], [[PARAM1]]
     36 ; CHECK: ret
     37 
     38 define i64 @test_psubw() {
     39 entry:
     40   %call = tail call { i64, double } @getFirstParam()
     41   %0 = extractvalue { i64, double } %call, 0
     42   %call2 = tail call { i64, double } @getSecondParam()
     43   %1 = extractvalue { i64, double } %call2, 0
     44   %__m1.0.insert.i = insertelement <1 x i64> undef, i64 %0, i32 0
     45   %__m2.0.insert.i = insertelement <1 x i64> undef, i64 %1, i32 0
     46   %2 = bitcast <1 x i64> %__m1.0.insert.i to <4 x i16>
     47   %3 = bitcast <4 x i16> %2 to x86_mmx
     48   %4 = bitcast <1 x i64> %__m2.0.insert.i to <4 x i16>
     49   %5 = bitcast <4 x i16> %4 to x86_mmx
     50   %6 = tail call x86_mmx @llvm.x86.mmx.psub.w(x86_mmx %3, x86_mmx %5) nounwind
     51   %7 = bitcast x86_mmx %6 to <4 x i16>
     52   %8 = bitcast <4 x i16> %7 to <1 x i64>
     53   %retval.0.extract.i15 = extractelement <1 x i64> %8, i32 0
     54   ret i64 %retval.0.extract.i15
     55 }
     56 
     57 ; CHECK-LABEL: test_psubw:
     58 ; CHECK:   callq getFirstParam
     59 ; CHECK:   movq %rax, [[TEMP:%[a-z0-9]+]]
     60 ; CHECK:   callq getSecondParam
     61 ; CHECK:   movd [[TEMP]], [[PARAM1:%[a-z0-9]+]]
     62 ; CHECK:   movd %rax, [[PARAM2:%[a-z0-9]+]]
     63 ; CHECK:   psubw [[PARAM2]], [[PARAM1]]
     64 ; CHECK: ret
     65 
     66 
     67 define i64 @test_psubd() {
     68 entry:
     69   %call = tail call { i64, double } @getFirstParam()
     70   %0 = extractvalue { i64, double } %call, 0
     71   %call2 = tail call { i64, double } @getSecondParam()
     72   %1 = extractvalue { i64, double } %call2, 0
     73   %__m1.0.insert.i = insertelement <1 x i64> undef, i64 %0, i32 0
     74   %__m2.0.insert.i = insertelement <1 x i64> undef, i64 %1, i32 0
     75   %2 = bitcast <1 x i64> %__m1.0.insert.i to <2 x i32>
     76   %3 = bitcast <2 x i32> %2 to x86_mmx
     77   %4 = bitcast <1 x i64> %__m2.0.insert.i to <2 x i32>
     78   %5 = bitcast <2 x i32> %4 to x86_mmx
     79   %6 = tail call x86_mmx @llvm.x86.mmx.psub.d(x86_mmx %3, x86_mmx %5) nounwind
     80   %7 = bitcast x86_mmx %6 to <2 x i32>
     81   %8 = bitcast <2 x i32> %7 to <1 x i64>
     82   %retval.0.extract.i15 = extractelement <1 x i64> %8, i32 0
     83   ret i64 %retval.0.extract.i15
     84 }
     85 
     86 ; CHECK-LABEL: test_psubd:
     87 ; CHECK:   callq getFirstParam
     88 ; CHECK:   movq %rax, [[TEMP:%[a-z0-9]+]]
     89 ; CHECK:   callq getSecondParam
     90 ; CHECK:   movd [[TEMP]], [[PARAM1:%[a-z0-9]+]]
     91 ; CHECK:   movd %rax, [[PARAM2:%[a-z0-9]+]]
     92 ; CHECK:   psubd [[PARAM2]], [[PARAM1]]
     93 ; CHECK: ret
     94 
     95 define i64 @test_psubsb() {
     96 entry:
     97   %call = tail call { i64, double } @getFirstParam()
     98   %0 = extractvalue { i64, double } %call, 0
     99   %call2 = tail call { i64, double } @getSecondParam()
    100   %1 = extractvalue { i64, double } %call2, 0
    101   %__m1.0.insert.i = insertelement <1 x i64> undef, i64 %0, i32 0
    102   %__m2.0.insert.i = insertelement <1 x i64> undef, i64 %1, i32 0
    103   %2 = bitcast <1 x i64> %__m1.0.insert.i to <8 x i8>
    104   %3 = bitcast <8 x i8> %2 to x86_mmx
    105   %4 = bitcast <1 x i64> %__m2.0.insert.i to <8 x i8>
    106   %5 = bitcast <8 x i8> %4 to x86_mmx
    107   %6 = tail call x86_mmx @llvm.x86.mmx.psubs.b(x86_mmx %3, x86_mmx %5) nounwind
    108   %7 = bitcast x86_mmx %6 to <8 x i8>
    109   %8 = bitcast <8 x i8> %7 to <1 x i64>
    110   %retval.0.extract.i15 = extractelement <1 x i64> %8, i32 0
    111   ret i64 %retval.0.extract.i15
    112 }
    113 
    114 ; CHECK-LABEL: test_psubsb:
    115 ; CHECK:   callq getFirstParam
    116 ; CHECK:   movq %rax, [[TEMP:%[a-z0-9]+]]
    117 ; CHECK:   callq getSecondParam
    118 ; CHECK:   movd [[TEMP]], [[PARAM1:%[a-z0-9]+]]
    119 ; CHECK:   movd %rax, [[PARAM2:%[a-z0-9]+]]
    120 ; CHECK:   psubsb [[PARAM2]], [[PARAM1]]
    121 ; CHECK: ret
    122 
    123 define i64 @test_psubswv() {
    124 entry:
    125   %call = tail call { i64, double } @getFirstParam()
    126   %0 = extractvalue { i64, double } %call, 0
    127   %call2 = tail call { i64, double } @getSecondParam()
    128   %1 = extractvalue { i64, double } %call2, 0
    129   %__m1.0.insert.i = insertelement <1 x i64> undef, i64 %0, i32 0
    130   %__m2.0.insert.i = insertelement <1 x i64> undef, i64 %1, i32 0
    131   %2 = bitcast <1 x i64> %__m1.0.insert.i to <4 x i16>
    132   %3 = bitcast <4 x i16> %2 to x86_mmx
    133   %4 = bitcast <1 x i64> %__m2.0.insert.i to <4 x i16>
    134   %5 = bitcast <4 x i16> %4 to x86_mmx
    135   %6 = tail call x86_mmx @llvm.x86.mmx.psubs.w(x86_mmx %3, x86_mmx %5) nounwind
    136   %7 = bitcast x86_mmx %6 to <4 x i16>
    137   %8 = bitcast <4 x i16> %7 to <1 x i64>
    138   %retval.0.extract.i15 = extractelement <1 x i64> %8, i32 0
    139   ret i64 %retval.0.extract.i15
    140 }
    141 
    142 ; CHECK-LABEL: test_psubswv:
    143 ; CHECK:   callq getFirstParam
    144 ; CHECK:   movq %rax, [[TEMP:%[a-z0-9]+]]
    145 ; CHECK:   callq getSecondParam
    146 ; CHECK:   movd [[TEMP]], [[PARAM1:%[a-z0-9]+]]
    147 ; CHECK:   movd %rax, [[PARAM2:%[a-z0-9]+]]
    148 ; CHECK:   psubsw [[PARAM2]], [[PARAM1]]
    149 ; CHECK: ret
    150 
    151 define i64 @test_psubusbv() {
    152 entry:
    153   %call = tail call { i64, double } @getFirstParam()
    154   %0 = extractvalue { i64, double } %call, 0
    155   %call2 = tail call { i64, double } @getSecondParam()
    156   %1 = extractvalue { i64, double } %call2, 0
    157   %__m1.0.insert.i = insertelement <1 x i64> undef, i64 %0, i32 0
    158   %__m2.0.insert.i = insertelement <1 x i64> undef, i64 %1, i32 0
    159   %2 = bitcast <1 x i64> %__m1.0.insert.i to <8 x i8>
    160   %3 = bitcast <8 x i8> %2 to x86_mmx
    161   %4 = bitcast <1 x i64> %__m2.0.insert.i to <8 x i8>
    162   %5 = bitcast <8 x i8> %4 to x86_mmx
    163   %6 = tail call x86_mmx @llvm.x86.mmx.psubus.b(x86_mmx %3, x86_mmx %5) nounwind
    164   %7 = bitcast x86_mmx %6 to <8 x i8>
    165   %8 = bitcast <8 x i8> %7 to <1 x i64>
    166   %retval.0.extract.i15 = extractelement <1 x i64> %8, i32 0
    167   ret i64 %retval.0.extract.i15
    168 }
    169 
    170 ; CHECK-LABEL: test_psubusbv:
    171 ; CHECK:   callq getFirstParam
    172 ; CHECK:   movq %rax, [[TEMP:%[a-z0-9]+]]
    173 ; CHECK:   callq getSecondParam
    174 ; CHECK:   movd [[TEMP]], [[PARAM1:%[a-z0-9]+]]
    175 ; CHECK:   movd %rax, [[PARAM2:%[a-z0-9]+]]
    176 ; CHECK:   psubusb [[PARAM2]], [[PARAM1]]
    177 ; CHECK: ret
    178 
    179 define i64 @test_psubuswv() {
    180 entry:
    181   %call = tail call { i64, double } @getFirstParam()
    182   %0 = extractvalue { i64, double } %call, 0
    183   %call2 = tail call { i64, double } @getSecondParam()
    184   %1 = extractvalue { i64, double } %call2, 0
    185   %__m1.0.insert.i = insertelement <1 x i64> undef, i64 %0, i32 0
    186   %__m2.0.insert.i = insertelement <1 x i64> undef, i64 %1, i32 0
    187   %2 = bitcast <1 x i64> %__m1.0.insert.i to <4 x i16>
    188   %3 = bitcast <4 x i16> %2 to x86_mmx
    189   %4 = bitcast <1 x i64> %__m2.0.insert.i to <4 x i16>
    190   %5 = bitcast <4 x i16> %4 to x86_mmx
    191   %6 = tail call x86_mmx @llvm.x86.mmx.psubus.w(x86_mmx %3, x86_mmx %5) nounwind
    192   %7 = bitcast x86_mmx %6 to <4 x i16>
    193   %8 = bitcast <4 x i16> %7 to <1 x i64>
    194   %retval.0.extract.i15 = extractelement <1 x i64> %8, i32 0
    195   ret i64 %retval.0.extract.i15
    196 }
    197 
    198 ; CHECK-LABEL: test_psubuswv:
    199 ; CHECK:   callq getFirstParam
    200 ; CHECK:   movq %rax, [[TEMP:%[a-z0-9]+]]
    201 ; CHECK:   callq getSecondParam
    202 ; CHECK:   movd [[TEMP]], [[PARAM1:%[a-z0-9]+]]
    203 ; CHECK:   movd %rax, [[PARAM2:%[a-z0-9]+]]
    204 ; CHECK:   psubusw [[PARAM2]], [[PARAM1]]
    205 ; CHECK: ret
    206 
    207 
    208 declare x86_mmx @llvm.x86.mmx.psubus.w(x86_mmx, x86_mmx) nounwind readnone
    209 
    210 declare x86_mmx @llvm.x86.mmx.psubus.b(x86_mmx, x86_mmx) nounwind readnone
    211 
    212 declare x86_mmx @llvm.x86.mmx.psubs.w(x86_mmx, x86_mmx) nounwind readnone
    213 
    214 declare x86_mmx @llvm.x86.mmx.psubs.b(x86_mmx, x86_mmx) nounwind readnone
    215 
    216 declare x86_mmx @llvm.x86.mmx.psub.d(x86_mmx, x86_mmx) nounwind readnone
    217 
    218 declare x86_mmx @llvm.x86.mmx.psub.w(x86_mmx, x86_mmx) nounwind readnone
    219 
    220 declare x86_mmx @llvm.x86.mmx.psub.b(x86_mmx, x86_mmx) nounwind readnone
    221