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
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:
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
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:
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
51 %my = and i16 %y, -256
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:
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
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:
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
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
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
143 %n1 = and i16 %n0, 255
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
163 %n1 = and i32 %n0, 65535
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
183 %n1 = and i64 %n0, 4294967295
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
207 %n1 = and i32 %n0, 65535
208 %r = xor i32 %y, %n1 ; swapped
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
227 %n1 = and i32 %n0, 65535
228 %r = xor i32 %n1, %x ; %x instead of %y
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
247 %n1 = and i32 %n0, 65535
248 %r = xor i32 %x, %n1 ; swapped, %x instead of %y
252 ; ============================================================================ ;
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
274 %n1 = and i32 %n0, 65535
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
297 %n1 = and i32 %n0, 65535
302 ; ============================================================================ ;
303 ; Negative tests. Should not be folded.
304 ; ============================================================================ ;
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
345 %n1 = and i32 %n0, 65535
346 call void @use32(i32 %n1)
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
384 %n1 = and i32 %n0, 65535
385 call void @use32(i32 %n0)
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
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
427 %n1 = and i32 %n0, 65535
428 %r = xor i32 %n1, %z ; instead of %y