AVX-512: added arithmetic and logical operations.
[oota-llvm.git] / test / CodeGen / X86 / x86-64-psub.ll
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