Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / test / CodeGen / X86 / unfold-masked-merge-scalar-constmask-lowhigh.ll
blob4a63eba04d85d25f8ac0d52e798113ac9a2d7e10
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi < %s | FileCheck %s --check-prefix=CHECK-NOBMI
3 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi < %s | FileCheck %s --check-prefix=CHECK-BMI
5 ; https://bugs.llvm.org/show_bug.cgi?id=37104
7 ; X:               [byte1][byte0]
8 ; Y: [byte3][byte2]
10 define i8 @out8_constmask(i8 %x, i8 %y) {
11 ; CHECK-NOBMI-LABEL: out8_constmask:
12 ; CHECK-NOBMI:       # %bb.0:
13 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
14 ; CHECK-NOBMI-NEXT:    andb $15, %dil
15 ; CHECK-NOBMI-NEXT:    andb $-16, %al
16 ; CHECK-NOBMI-NEXT:    orb %dil, %al
17 ; CHECK-NOBMI-NEXT:    # kill: def $al killed $al killed $eax
18 ; CHECK-NOBMI-NEXT:    retq
20 ; CHECK-BMI-LABEL: out8_constmask:
21 ; CHECK-BMI:       # %bb.0:
22 ; CHECK-BMI-NEXT:    movl %esi, %eax
23 ; CHECK-BMI-NEXT:    andb $15, %dil
24 ; CHECK-BMI-NEXT:    andb $-16, %al
25 ; CHECK-BMI-NEXT:    orb %dil, %al
26 ; CHECK-BMI-NEXT:    # kill: def $al killed $al killed $eax
27 ; CHECK-BMI-NEXT:    retq
28   %mx = and i8 %x, 15
29   %my = and i8 %y, -16
30   %r = or i8 %mx, %my
31   ret i8 %r
34 define i16 @out16_constmask(i16 %x, i16 %y) {
35 ; CHECK-NOBMI-LABEL: out16_constmask:
36 ; CHECK-NOBMI:       # %bb.0:
37 ; CHECK-NOBMI-NEXT:    movzbl %dil, %eax
38 ; CHECK-NOBMI-NEXT:    andl $-256, %esi
39 ; CHECK-NOBMI-NEXT:    orl %esi, %eax
40 ; CHECK-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
41 ; CHECK-NOBMI-NEXT:    retq
43 ; CHECK-BMI-LABEL: out16_constmask:
44 ; CHECK-BMI:       # %bb.0:
45 ; CHECK-BMI-NEXT:    movzbl %dil, %eax
46 ; CHECK-BMI-NEXT:    andl $-256, %esi
47 ; CHECK-BMI-NEXT:    orl %esi, %eax
48 ; CHECK-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
49 ; CHECK-BMI-NEXT:    retq
50   %mx = and i16 %x, 255
51   %my = and i16 %y, -256
52   %r = or i16 %mx, %my
53   ret i16 %r
56 define i32 @out32_constmask(i32 %x, i32 %y) {
57 ; CHECK-NOBMI-LABEL: out32_constmask:
58 ; CHECK-NOBMI:       # %bb.0:
59 ; CHECK-NOBMI-NEXT:    movzwl %di, %eax
60 ; CHECK-NOBMI-NEXT:    andl $-65536, %esi # imm = 0xFFFF0000
61 ; CHECK-NOBMI-NEXT:    orl %esi, %eax
62 ; CHECK-NOBMI-NEXT:    retq
64 ; CHECK-BMI-LABEL: out32_constmask:
65 ; CHECK-BMI:       # %bb.0:
66 ; CHECK-BMI-NEXT:    movzwl %di, %eax
67 ; CHECK-BMI-NEXT:    andl $-65536, %esi # imm = 0xFFFF0000
68 ; CHECK-BMI-NEXT:    orl %esi, %eax
69 ; CHECK-BMI-NEXT:    retq
70   %mx = and i32 %x, 65535
71   %my = and i32 %y, -65536
72   %r = or i32 %mx, %my
73   ret i32 %r
76 define i64 @out64_constmask(i64 %x, i64 %y) {
77 ; CHECK-NOBMI-LABEL: out64_constmask:
78 ; CHECK-NOBMI:       # %bb.0:
79 ; CHECK-NOBMI-NEXT:    movl %edi, %ecx
80 ; CHECK-NOBMI-NEXT:    movabsq $-4294967296, %rax # imm = 0xFFFFFFFF00000000
81 ; CHECK-NOBMI-NEXT:    andq %rsi, %rax
82 ; CHECK-NOBMI-NEXT:    orq %rcx, %rax
83 ; CHECK-NOBMI-NEXT:    retq
85 ; CHECK-BMI-LABEL: out64_constmask:
86 ; CHECK-BMI:       # %bb.0:
87 ; CHECK-BMI-NEXT:    movl %edi, %ecx
88 ; CHECK-BMI-NEXT:    movabsq $-4294967296, %rax # imm = 0xFFFFFFFF00000000
89 ; CHECK-BMI-NEXT:    andq %rsi, %rax
90 ; CHECK-BMI-NEXT:    orq %rcx, %rax
91 ; CHECK-BMI-NEXT:    retq
92   %mx = and i64 %x, 4294967295
93   %my = and i64 %y, -4294967296
94   %r = or i64 %mx, %my
95   ret i64 %r
98 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
99 ; Should be the same as the previous one.
100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
102 define i8 @in8_constmask(i8 %x, i8 %y) {
103 ; CHECK-NOBMI-LABEL: in8_constmask:
104 ; CHECK-NOBMI:       # %bb.0:
105 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
106 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
107 ; CHECK-NOBMI-NEXT:    andb $15, %dil
108 ; CHECK-NOBMI-NEXT:    xorb %dil, %al
109 ; CHECK-NOBMI-NEXT:    # kill: def $al killed $al killed $eax
110 ; CHECK-NOBMI-NEXT:    retq
112 ; CHECK-BMI-LABEL: in8_constmask:
113 ; CHECK-BMI:       # %bb.0:
114 ; CHECK-BMI-NEXT:    movl %esi, %eax
115 ; CHECK-BMI-NEXT:    xorl %esi, %edi
116 ; CHECK-BMI-NEXT:    andb $15, %dil
117 ; CHECK-BMI-NEXT:    xorb %dil, %al
118 ; CHECK-BMI-NEXT:    # kill: def $al killed $al killed $eax
119 ; CHECK-BMI-NEXT:    retq
120   %n0 = xor i8 %x, %y
121   %n1 = and i8 %n0, 15
122   %r = xor i8 %n1, %y
123   ret i8 %r
126 define i16 @in16_constmask(i16 %x, i16 %y) {
127 ; CHECK-NOBMI-LABEL: in16_constmask:
128 ; CHECK-NOBMI:       # %bb.0:
129 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
130 ; CHECK-NOBMI-NEXT:    movzbl %dil, %eax
131 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
132 ; CHECK-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
133 ; CHECK-NOBMI-NEXT:    retq
135 ; CHECK-BMI-LABEL: in16_constmask:
136 ; CHECK-BMI:       # %bb.0:
137 ; CHECK-BMI-NEXT:    xorl %esi, %edi
138 ; CHECK-BMI-NEXT:    movzbl %dil, %eax
139 ; CHECK-BMI-NEXT:    xorl %esi, %eax
140 ; CHECK-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
141 ; CHECK-BMI-NEXT:    retq
142   %n0 = xor i16 %x, %y
143   %n1 = and i16 %n0, 255
144   %r = xor i16 %n1, %y
145   ret i16 %r
148 define i32 @in32_constmask(i32 %x, i32 %y) {
149 ; CHECK-NOBMI-LABEL: in32_constmask:
150 ; CHECK-NOBMI:       # %bb.0:
151 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
152 ; CHECK-NOBMI-NEXT:    movzwl %di, %eax
153 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
154 ; CHECK-NOBMI-NEXT:    retq
156 ; CHECK-BMI-LABEL: in32_constmask:
157 ; CHECK-BMI:       # %bb.0:
158 ; CHECK-BMI-NEXT:    xorl %esi, %edi
159 ; CHECK-BMI-NEXT:    movzwl %di, %eax
160 ; CHECK-BMI-NEXT:    xorl %esi, %eax
161 ; CHECK-BMI-NEXT:    retq
162   %n0 = xor i32 %x, %y
163   %n1 = and i32 %n0, 65535
164   %r = xor i32 %n1, %y
165   ret i32 %r
168 define i64 @in64_constmask(i64 %x, i64 %y) {
169 ; CHECK-NOBMI-LABEL: in64_constmask:
170 ; CHECK-NOBMI:       # %bb.0:
171 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
172 ; CHECK-NOBMI-NEXT:    xorl %edi, %eax
173 ; CHECK-NOBMI-NEXT:    xorq %rsi, %rax
174 ; CHECK-NOBMI-NEXT:    retq
176 ; CHECK-BMI-LABEL: in64_constmask:
177 ; CHECK-BMI:       # %bb.0:
178 ; CHECK-BMI-NEXT:    movl %esi, %eax
179 ; CHECK-BMI-NEXT:    xorl %edi, %eax
180 ; CHECK-BMI-NEXT:    xorq %rsi, %rax
181 ; CHECK-BMI-NEXT:    retq
182   %n0 = xor i64 %x, %y
183   %n1 = and i64 %n0, 4294967295
184   %r = xor i64 %n1, %y
185   ret i64 %r
188 ; ============================================================================ ;
189 ; Constant Commutativity tests.
190 ; ============================================================================ ;
192 define i32 @in_constmask_commutativity_0_1(i32 %x, i32 %y) {
193 ; CHECK-NOBMI-LABEL: in_constmask_commutativity_0_1:
194 ; CHECK-NOBMI:       # %bb.0:
195 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
196 ; CHECK-NOBMI-NEXT:    movzwl %di, %eax
197 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
198 ; CHECK-NOBMI-NEXT:    retq
200 ; CHECK-BMI-LABEL: in_constmask_commutativity_0_1:
201 ; CHECK-BMI:       # %bb.0:
202 ; CHECK-BMI-NEXT:    xorl %esi, %edi
203 ; CHECK-BMI-NEXT:    movzwl %di, %eax
204 ; CHECK-BMI-NEXT:    xorl %esi, %eax
205 ; CHECK-BMI-NEXT:    retq
206   %n0 = xor i32 %x, %y
207   %n1 = and i32 %n0, 65535
208   %r = xor i32 %y, %n1 ; swapped
209   ret i32 %r
212 define i32 @in_constmask_commutativity_1_0(i32 %x, i32 %y) {
213 ; CHECK-NOBMI-LABEL: in_constmask_commutativity_1_0:
214 ; CHECK-NOBMI:       # %bb.0:
215 ; CHECK-NOBMI-NEXT:    xorl %edi, %esi
216 ; CHECK-NOBMI-NEXT:    movzwl %si, %eax
217 ; CHECK-NOBMI-NEXT:    xorl %edi, %eax
218 ; CHECK-NOBMI-NEXT:    retq
220 ; CHECK-BMI-LABEL: in_constmask_commutativity_1_0:
221 ; CHECK-BMI:       # %bb.0:
222 ; CHECK-BMI-NEXT:    xorl %edi, %esi
223 ; CHECK-BMI-NEXT:    movzwl %si, %eax
224 ; CHECK-BMI-NEXT:    xorl %edi, %eax
225 ; CHECK-BMI-NEXT:    retq
226   %n0 = xor i32 %x, %y
227   %n1 = and i32 %n0, 65535
228   %r = xor i32 %n1, %x ; %x instead of %y
229   ret i32 %r
232 define i32 @in_constmask_commutativity_1_1(i32 %x, i32 %y) {
233 ; CHECK-NOBMI-LABEL: in_constmask_commutativity_1_1:
234 ; CHECK-NOBMI:       # %bb.0:
235 ; CHECK-NOBMI-NEXT:    xorl %edi, %esi
236 ; CHECK-NOBMI-NEXT:    movzwl %si, %eax
237 ; CHECK-NOBMI-NEXT:    xorl %edi, %eax
238 ; CHECK-NOBMI-NEXT:    retq
240 ; CHECK-BMI-LABEL: in_constmask_commutativity_1_1:
241 ; CHECK-BMI:       # %bb.0:
242 ; CHECK-BMI-NEXT:    xorl %edi, %esi
243 ; CHECK-BMI-NEXT:    movzwl %si, %eax
244 ; CHECK-BMI-NEXT:    xorl %edi, %eax
245 ; CHECK-BMI-NEXT:    retq
246   %n0 = xor i32 %x, %y
247   %n1 = and i32 %n0, 65535
248   %r = xor i32 %x, %n1 ; swapped, %x instead of %y
249   ret i32 %r
252 ; ============================================================================ ;
253 ; Y is an 'and' too.
254 ; ============================================================================ ;
256 define i32 @in_complex_y0_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
257 ; CHECK-NOBMI-LABEL: in_complex_y0_constmask:
258 ; CHECK-NOBMI:       # %bb.0:
259 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
260 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
261 ; CHECK-NOBMI-NEXT:    movzwl %di, %eax
262 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
263 ; CHECK-NOBMI-NEXT:    retq
265 ; CHECK-BMI-LABEL: in_complex_y0_constmask:
266 ; CHECK-BMI:       # %bb.0:
267 ; CHECK-BMI-NEXT:    andl %edx, %esi
268 ; CHECK-BMI-NEXT:    xorl %esi, %edi
269 ; CHECK-BMI-NEXT:    movzwl %di, %eax
270 ; CHECK-BMI-NEXT:    xorl %esi, %eax
271 ; CHECK-BMI-NEXT:    retq
272   %y = and i32 %y_hi, %y_low
273   %n0 = xor i32 %x, %y
274   %n1 = and i32 %n0, 65535
275   %r = xor i32 %n1, %y
276   ret i32 %r
279 define i32 @in_complex_y1_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
280 ; CHECK-NOBMI-LABEL: in_complex_y1_constmask:
281 ; CHECK-NOBMI:       # %bb.0:
282 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
283 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
284 ; CHECK-NOBMI-NEXT:    movzwl %di, %eax
285 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
286 ; CHECK-NOBMI-NEXT:    retq
288 ; CHECK-BMI-LABEL: in_complex_y1_constmask:
289 ; CHECK-BMI:       # %bb.0:
290 ; CHECK-BMI-NEXT:    andl %edx, %esi
291 ; CHECK-BMI-NEXT:    xorl %esi, %edi
292 ; CHECK-BMI-NEXT:    movzwl %di, %eax
293 ; CHECK-BMI-NEXT:    xorl %esi, %eax
294 ; CHECK-BMI-NEXT:    retq
295   %y = and i32 %y_hi, %y_low
296   %n0 = xor i32 %x, %y
297   %n1 = and i32 %n0, 65535
298   %r = xor i32 %y, %n1
299   ret i32 %r
302 ; ============================================================================ ;
303 ; Negative tests. Should not be folded.
304 ; ============================================================================ ;
306 ; Multi-use tests.
308 declare void @use32(i32) nounwind
310 define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
311 ; CHECK-NOBMI-LABEL: in_multiuse_A_constmask:
312 ; CHECK-NOBMI:       # %bb.0:
313 ; CHECK-NOBMI-NEXT:    pushq %rbp
314 ; CHECK-NOBMI-NEXT:    pushq %rbx
315 ; CHECK-NOBMI-NEXT:    pushq %rax
316 ; CHECK-NOBMI-NEXT:    movl %esi, %ebx
317 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
318 ; CHECK-NOBMI-NEXT:    movzwl %di, %ebp
319 ; CHECK-NOBMI-NEXT:    movl %ebp, %edi
320 ; CHECK-NOBMI-NEXT:    callq use32
321 ; CHECK-NOBMI-NEXT:    xorl %ebx, %ebp
322 ; CHECK-NOBMI-NEXT:    movl %ebp, %eax
323 ; CHECK-NOBMI-NEXT:    addq $8, %rsp
324 ; CHECK-NOBMI-NEXT:    popq %rbx
325 ; CHECK-NOBMI-NEXT:    popq %rbp
326 ; CHECK-NOBMI-NEXT:    retq
328 ; CHECK-BMI-LABEL: in_multiuse_A_constmask:
329 ; CHECK-BMI:       # %bb.0:
330 ; CHECK-BMI-NEXT:    pushq %rbp
331 ; CHECK-BMI-NEXT:    pushq %rbx
332 ; CHECK-BMI-NEXT:    pushq %rax
333 ; CHECK-BMI-NEXT:    movl %esi, %ebx
334 ; CHECK-BMI-NEXT:    xorl %esi, %edi
335 ; CHECK-BMI-NEXT:    movzwl %di, %ebp
336 ; CHECK-BMI-NEXT:    movl %ebp, %edi
337 ; CHECK-BMI-NEXT:    callq use32
338 ; CHECK-BMI-NEXT:    xorl %ebx, %ebp
339 ; CHECK-BMI-NEXT:    movl %ebp, %eax
340 ; CHECK-BMI-NEXT:    addq $8, %rsp
341 ; CHECK-BMI-NEXT:    popq %rbx
342 ; CHECK-BMI-NEXT:    popq %rbp
343 ; CHECK-BMI-NEXT:    retq
344   %n0 = xor i32 %x, %y
345   %n1 = and i32 %n0, 65535
346   call void @use32(i32 %n1)
347   %r = xor i32 %n1, %y
348   ret i32 %r
351 define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {
352 ; CHECK-NOBMI-LABEL: in_multiuse_B_constmask:
353 ; CHECK-NOBMI:       # %bb.0:
354 ; CHECK-NOBMI-NEXT:    pushq %rbp
355 ; CHECK-NOBMI-NEXT:    pushq %rbx
356 ; CHECK-NOBMI-NEXT:    pushq %rax
357 ; CHECK-NOBMI-NEXT:    movl %esi, %ebx
358 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
359 ; CHECK-NOBMI-NEXT:    movzwl %di, %ebp
360 ; CHECK-NOBMI-NEXT:    callq use32
361 ; CHECK-NOBMI-NEXT:    xorl %ebx, %ebp
362 ; CHECK-NOBMI-NEXT:    movl %ebp, %eax
363 ; CHECK-NOBMI-NEXT:    addq $8, %rsp
364 ; CHECK-NOBMI-NEXT:    popq %rbx
365 ; CHECK-NOBMI-NEXT:    popq %rbp
366 ; CHECK-NOBMI-NEXT:    retq
368 ; CHECK-BMI-LABEL: in_multiuse_B_constmask:
369 ; CHECK-BMI:       # %bb.0:
370 ; CHECK-BMI-NEXT:    pushq %rbp
371 ; CHECK-BMI-NEXT:    pushq %rbx
372 ; CHECK-BMI-NEXT:    pushq %rax
373 ; CHECK-BMI-NEXT:    movl %esi, %ebx
374 ; CHECK-BMI-NEXT:    xorl %esi, %edi
375 ; CHECK-BMI-NEXT:    movzwl %di, %ebp
376 ; CHECK-BMI-NEXT:    callq use32
377 ; CHECK-BMI-NEXT:    xorl %ebx, %ebp
378 ; CHECK-BMI-NEXT:    movl %ebp, %eax
379 ; CHECK-BMI-NEXT:    addq $8, %rsp
380 ; CHECK-BMI-NEXT:    popq %rbx
381 ; CHECK-BMI-NEXT:    popq %rbp
382 ; CHECK-BMI-NEXT:    retq
383   %n0 = xor i32 %x, %y
384   %n1 = and i32 %n0, 65535
385   call void @use32(i32 %n0)
386   %r = xor i32 %n1, %y
387   ret i32 %r
390 ; Various bad variants
392 define i32 @n0_badconstmask(i32 %x, i32 %y) {
393 ; CHECK-NOBMI-LABEL: n0_badconstmask:
394 ; CHECK-NOBMI:       # %bb.0:
395 ; CHECK-NOBMI-NEXT:    movzwl %di, %eax
396 ; CHECK-NOBMI-NEXT:    andl $-65535, %esi # imm = 0xFFFF0001
397 ; CHECK-NOBMI-NEXT:    orl %esi, %eax
398 ; CHECK-NOBMI-NEXT:    retq
400 ; CHECK-BMI-LABEL: n0_badconstmask:
401 ; CHECK-BMI:       # %bb.0:
402 ; CHECK-BMI-NEXT:    movzwl %di, %eax
403 ; CHECK-BMI-NEXT:    andl $-65535, %esi # imm = 0xFFFF0001
404 ; CHECK-BMI-NEXT:    orl %esi, %eax
405 ; CHECK-BMI-NEXT:    retq
406   %mx = and i32 %x, 65535
407   %my = and i32 %y, -65535 ; instead of -65536
408   %r = or i32 %mx, %my
409   ret i32 %r
412 define i32 @n1_thirdvar_constmask(i32 %x, i32 %y, i32 %z) {
413 ; CHECK-NOBMI-LABEL: n1_thirdvar_constmask:
414 ; CHECK-NOBMI:       # %bb.0:
415 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
416 ; CHECK-NOBMI-NEXT:    movzwl %di, %eax
417 ; CHECK-NOBMI-NEXT:    xorl %edx, %eax
418 ; CHECK-NOBMI-NEXT:    retq
420 ; CHECK-BMI-LABEL: n1_thirdvar_constmask:
421 ; CHECK-BMI:       # %bb.0:
422 ; CHECK-BMI-NEXT:    xorl %esi, %edi
423 ; CHECK-BMI-NEXT:    movzwl %di, %eax
424 ; CHECK-BMI-NEXT:    xorl %edx, %eax
425 ; CHECK-BMI-NEXT:    retq
426   %n0 = xor i32 %x, %y
427   %n1 = and i32 %n0, 65535
428   %r = xor i32 %n1, %z ; instead of %y
429   ret i32 %r