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