Add a triple to switch.ll test.
[oota-llvm.git] / test / CodeGen / X86 / x86-64-psub.ll
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