[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / X86 / combine-sub.ll
blob0dd390d612e4f8005bf6becbdbdc0cf6bf40995b
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefixes=CHECK,SSE
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=CHECK,AVX
5 ; fold (sub x, 0) -> x
6 define <4 x i32> @combine_vec_sub_zero(<4 x i32> %a) {
7 ; CHECK-LABEL: combine_vec_sub_zero:
8 ; CHECK:       # %bb.0:
9 ; CHECK-NEXT:    retq
10   %1 = sub <4 x i32> %a, zeroinitializer
11   ret <4 x i32> %1
14 ; fold (sub x, x) -> 0
15 define <4 x i32> @combine_vec_sub_self(<4 x i32> %a) {
16 ; SSE-LABEL: combine_vec_sub_self:
17 ; SSE:       # %bb.0:
18 ; SSE-NEXT:    xorps %xmm0, %xmm0
19 ; SSE-NEXT:    retq
21 ; AVX-LABEL: combine_vec_sub_self:
22 ; AVX:       # %bb.0:
23 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
24 ; AVX-NEXT:    retq
25   %1 = sub <4 x i32> %a, %a
26   ret <4 x i32> %1
29 ; fold (sub x, c) -> (add x, -c)
30 define <4 x i32> @combine_vec_sub_constant(<4 x i32> %x) {
31 ; SSE-LABEL: combine_vec_sub_constant:
32 ; SSE:       # %bb.0:
33 ; SSE-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
34 ; SSE-NEXT:    retq
36 ; AVX-LABEL: combine_vec_sub_constant:
37 ; AVX:       # %bb.0:
38 ; AVX-NEXT:    vpsubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
39 ; AVX-NEXT:    retq
40   %1 = sub <4 x i32> %x, <i32 0, i32 1, i32 2, i32 3>
41   ret <4 x i32> %1
44 ; Canonicalize (sub -1, x) -> ~x, i.e. (xor x, -1)
45 define <4 x i32> @combine_vec_sub_negone(<4 x i32> %x) {
46 ; SSE-LABEL: combine_vec_sub_negone:
47 ; SSE:       # %bb.0:
48 ; SSE-NEXT:    pcmpeqd %xmm1, %xmm1
49 ; SSE-NEXT:    pxor %xmm1, %xmm0
50 ; SSE-NEXT:    retq
52 ; AVX-LABEL: combine_vec_sub_negone:
53 ; AVX:       # %bb.0:
54 ; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
55 ; AVX-NEXT:    vpxor %xmm1, %xmm0, %xmm0
56 ; AVX-NEXT:    retq
57   %1 = sub <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %x
58   ret <4 x i32> %1
61 ; fold A-(A-B) -> B
62 define <4 x i32> @combine_vec_sub_sub(<4 x i32> %a, <4 x i32> %b) {
63 ; SSE-LABEL: combine_vec_sub_sub:
64 ; SSE:       # %bb.0:
65 ; SSE-NEXT:    movaps %xmm1, %xmm0
66 ; SSE-NEXT:    retq
68 ; AVX-LABEL: combine_vec_sub_sub:
69 ; AVX:       # %bb.0:
70 ; AVX-NEXT:    vmovaps %xmm1, %xmm0
71 ; AVX-NEXT:    retq
72   %1 = sub <4 x i32> %a, %b
73   %2 = sub <4 x i32> %a, %1
74   ret <4 x i32> %2
77 ; fold (A+B)-A -> B
78 define <4 x i32> @combine_vec_sub_add0(<4 x i32> %a, <4 x i32> %b) {
79 ; SSE-LABEL: combine_vec_sub_add0:
80 ; SSE:       # %bb.0:
81 ; SSE-NEXT:    movaps %xmm1, %xmm0
82 ; SSE-NEXT:    retq
84 ; AVX-LABEL: combine_vec_sub_add0:
85 ; AVX:       # %bb.0:
86 ; AVX-NEXT:    vmovaps %xmm1, %xmm0
87 ; AVX-NEXT:    retq
88   %1 = add <4 x i32> %a, %b
89   %2 = sub <4 x i32> %1, %a
90   ret <4 x i32> %2
93 ; fold (A+B)-B -> A
94 define <4 x i32> @combine_vec_sub_add1(<4 x i32> %a, <4 x i32> %b) {
95 ; CHECK-LABEL: combine_vec_sub_add1:
96 ; CHECK:       # %bb.0:
97 ; CHECK-NEXT:    retq
98   %1 = add <4 x i32> %a, %b
99   %2 = sub <4 x i32> %1, %b
100   ret <4 x i32> %2
103 ; fold C2-(A+C1) -> (C2-C1)-A
104 define <4 x i32> @combine_vec_sub_constant_add(<4 x i32> %a) {
105 ; SSE-LABEL: combine_vec_sub_constant_add:
106 ; SSE:       # %bb.0:
107 ; SSE-NEXT:    movdqa {{.*#+}} xmm1 = [3,1,4294967295,4294967293]
108 ; SSE-NEXT:    psubd %xmm0, %xmm1
109 ; SSE-NEXT:    movdqa %xmm1, %xmm0
110 ; SSE-NEXT:    retq
112 ; AVX-LABEL: combine_vec_sub_constant_add:
113 ; AVX:       # %bb.0:
114 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm1 = [3,1,4294967295,4294967293]
115 ; AVX-NEXT:    vpsubd %xmm0, %xmm1, %xmm0
116 ; AVX-NEXT:    retq
117   %1 = add <4 x i32> %a, <i32 0, i32 1, i32 2, i32 3>
118   %2 = sub <4 x i32> <i32 3, i32 2, i32 1, i32 0>, %1
119   ret <4 x i32> %2
122 ; fold ((A+(B+C))-B) -> A+C
123 define <4 x i32> @combine_vec_sub_add_add(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
124 ; SSE-LABEL: combine_vec_sub_add_add:
125 ; SSE:       # %bb.0:
126 ; SSE-NEXT:    paddd %xmm2, %xmm0
127 ; SSE-NEXT:    retq
129 ; AVX-LABEL: combine_vec_sub_add_add:
130 ; AVX:       # %bb.0:
131 ; AVX-NEXT:    vpaddd %xmm2, %xmm0, %xmm0
132 ; AVX-NEXT:    retq
133   %1 = add <4 x i32> %b, %c
134   %2 = add <4 x i32> %a, %1
135   %3 = sub <4 x i32> %2, %b
136   ret <4 x i32> %3
139 ; fold ((A+(B-C))-B) -> A-C
140 define <4 x i32> @combine_vec_sub_add_sub(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
141 ; SSE-LABEL: combine_vec_sub_add_sub:
142 ; SSE:       # %bb.0:
143 ; SSE-NEXT:    psubd %xmm2, %xmm0
144 ; SSE-NEXT:    retq
146 ; AVX-LABEL: combine_vec_sub_add_sub:
147 ; AVX:       # %bb.0:
148 ; AVX-NEXT:    vpsubd %xmm2, %xmm0, %xmm0
149 ; AVX-NEXT:    retq
150   %1 = sub <4 x i32> %b, %c
151   %2 = add <4 x i32> %a, %1
152   %3 = sub <4 x i32> %2, %b
153   ret <4 x i32> %3
156 ; fold ((A-(B-C))-C) -> A-B
157 define <4 x i32> @combine_vec_sub_sub_sub(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
158 ; SSE-LABEL: combine_vec_sub_sub_sub:
159 ; SSE:       # %bb.0:
160 ; SSE-NEXT:    psubd %xmm1, %xmm0
161 ; SSE-NEXT:    retq
163 ; AVX-LABEL: combine_vec_sub_sub_sub:
164 ; AVX:       # %bb.0:
165 ; AVX-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
166 ; AVX-NEXT:    retq
167   %1 = sub <4 x i32> %b, %c
168   %2 = sub <4 x i32> %a, %1
169   %3 = sub <4 x i32> %2, %c
170   ret <4 x i32> %3
173 ; fold undef-A -> undef
174 define <4 x i32> @combine_vec_sub_undef0(<4 x i32> %a) {
175 ; CHECK-LABEL: combine_vec_sub_undef0:
176 ; CHECK:       # %bb.0:
177 ; CHECK-NEXT:    retq
178   %1 = sub <4 x i32> undef, %a
179   ret <4 x i32> %1
182 ; fold A-undef -> undef
183 define <4 x i32> @combine_vec_sub_undef1(<4 x i32> %a) {
184 ; CHECK-LABEL: combine_vec_sub_undef1:
185 ; CHECK:       # %bb.0:
186 ; CHECK-NEXT:    retq
187   %1 = sub <4 x i32> %a, undef
188   ret <4 x i32> %1
191 ; sub X, (sext Y i1) -> add X, (and Y 1)
192 define <4 x i32> @combine_vec_add_sext(<4 x i32> %x, <4 x i1> %y) {
193 ; SSE-LABEL: combine_vec_add_sext:
194 ; SSE:       # %bb.0:
195 ; SSE-NEXT:    pslld $31, %xmm1
196 ; SSE-NEXT:    psrad $31, %xmm1
197 ; SSE-NEXT:    psubd %xmm1, %xmm0
198 ; SSE-NEXT:    retq
200 ; AVX-LABEL: combine_vec_add_sext:
201 ; AVX:       # %bb.0:
202 ; AVX-NEXT:    vpslld $31, %xmm1, %xmm1
203 ; AVX-NEXT:    vpsrad $31, %xmm1, %xmm1
204 ; AVX-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
205 ; AVX-NEXT:    retq
206   %1 = sext <4 x i1> %y to <4 x i32>
207   %2 = sub <4 x i32> %x, %1
208   ret <4 x i32> %2
211 ; sub X, (sextinreg Y i1) -> add X, (and Y 1)
212 define <4 x i32> @combine_vec_sub_sextinreg(<4 x i32> %x, <4 x i32> %y) {
213 ; SSE-LABEL: combine_vec_sub_sextinreg:
214 ; SSE:       # %bb.0:
215 ; SSE-NEXT:    pslld $31, %xmm1
216 ; SSE-NEXT:    psrad $31, %xmm1
217 ; SSE-NEXT:    psubd %xmm1, %xmm0
218 ; SSE-NEXT:    retq
220 ; AVX-LABEL: combine_vec_sub_sextinreg:
221 ; AVX:       # %bb.0:
222 ; AVX-NEXT:    vpslld $31, %xmm1, %xmm1
223 ; AVX-NEXT:    vpsrad $31, %xmm1, %xmm1
224 ; AVX-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
225 ; AVX-NEXT:    retq
226   %1 = shl <4 x i32> %y, <i32 31, i32 31, i32 31, i32 31>
227   %2 = ashr <4 x i32> %1, <i32 31, i32 31, i32 31, i32 31>
228   %3 = sub <4 x i32> %x, %2
229   ret <4 x i32> %3
232 ; sub C1, (xor X, C1) -> add (xor X, ~C2), C1+1
233 define i32 @combine_sub_xor_consts(i32 %x) {
234 ; CHECK-LABEL: combine_sub_xor_consts:
235 ; CHECK:       # %bb.0:
236 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
237 ; CHECK-NEXT:    xorl $-32, %edi
238 ; CHECK-NEXT:    leal 33(%rdi), %eax
239 ; CHECK-NEXT:    retq
240   %xor = xor i32 %x, 31
241   %sub = sub i32 32, %xor
242   ret i32 %sub
245 define <4 x i32> @combine_vec_sub_xor_consts(<4 x i32> %x) {
246 ; SSE-LABEL: combine_vec_sub_xor_consts:
247 ; SSE:       # %bb.0:
248 ; SSE-NEXT:    pxor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
249 ; SSE-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
250 ; SSE-NEXT:    retq
252 ; AVX-LABEL: combine_vec_sub_xor_consts:
253 ; AVX:       # %bb.0:
254 ; AVX-NEXT:    vpxor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
255 ; AVX-NEXT:    vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
256 ; AVX-NEXT:    retq
257   %xor = xor <4 x i32> %x, <i32 28, i32 29, i32 -1, i32 -31>
258   %sub = sub <4 x i32> <i32 1, i32 2, i32 3, i32 4>, %xor
259   ret <4 x i32> %sub
262 define <4 x i32> @combine_vec_neg_xor_consts(<4 x i32> %x) {
263 ; SSE-LABEL: combine_vec_neg_xor_consts:
264 ; SSE:       # %bb.0:
265 ; SSE-NEXT:    pcmpeqd %xmm1, %xmm1
266 ; SSE-NEXT:    psubd %xmm1, %xmm0
267 ; SSE-NEXT:    retq
269 ; AVX-LABEL: combine_vec_neg_xor_consts:
270 ; AVX:       # %bb.0:
271 ; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
272 ; AVX-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
273 ; AVX-NEXT:    retq
274   %xor = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
275   %sub = sub <4 x i32> zeroinitializer, %xor
276   ret <4 x i32> %sub