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