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: # kill: def $esi killed $esi def $rsi
14 ; CHECK-NOBMI-NEXT: # kill: def $edi killed $edi def $rdi
15 ; CHECK-NOBMI-NEXT: andb $15, %dil
16 ; CHECK-NOBMI-NEXT: andb $-16, %sil
17 ; CHECK-NOBMI-NEXT: leal (%rsi,%rdi), %eax
18 ; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax
19 ; CHECK-NOBMI-NEXT: retq
21 ; CHECK-BMI-LABEL: out8_constmask:
23 ; CHECK-BMI-NEXT: # kill: def $esi killed $esi def $rsi
24 ; CHECK-BMI-NEXT: # kill: def $edi killed $edi def $rdi
25 ; CHECK-BMI-NEXT: andb $15, %dil
26 ; CHECK-BMI-NEXT: andb $-16, %sil
27 ; CHECK-BMI-NEXT: leal (%rsi,%rdi), %eax
28 ; CHECK-BMI-NEXT: # kill: def $al killed $al killed $eax
29 ; CHECK-BMI-NEXT: retq
36 define i16 @out16_constmask(i16 %x, i16 %y) {
37 ; CHECK-NOBMI-LABEL: out16_constmask:
38 ; CHECK-NOBMI: # %bb.0:
39 ; CHECK-NOBMI-NEXT: movzbl %dil, %eax
40 ; CHECK-NOBMI-NEXT: andl $-256, %esi
41 ; CHECK-NOBMI-NEXT: orl %esi, %eax
42 ; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax
43 ; CHECK-NOBMI-NEXT: retq
45 ; CHECK-BMI-LABEL: out16_constmask:
47 ; CHECK-BMI-NEXT: movzbl %dil, %eax
48 ; CHECK-BMI-NEXT: andl $-256, %esi
49 ; CHECK-BMI-NEXT: orl %esi, %eax
50 ; CHECK-BMI-NEXT: # kill: def $ax killed $ax killed $eax
51 ; CHECK-BMI-NEXT: retq
53 %my = and i16 %y, -256
58 define i32 @out32_constmask(i32 %x, i32 %y) {
59 ; CHECK-NOBMI-LABEL: out32_constmask:
60 ; CHECK-NOBMI: # %bb.0:
61 ; CHECK-NOBMI-NEXT: movzwl %di, %eax
62 ; CHECK-NOBMI-NEXT: andl $-65536, %esi # imm = 0xFFFF0000
63 ; CHECK-NOBMI-NEXT: orl %esi, %eax
64 ; CHECK-NOBMI-NEXT: retq
66 ; CHECK-BMI-LABEL: out32_constmask:
68 ; CHECK-BMI-NEXT: movzwl %di, %eax
69 ; CHECK-BMI-NEXT: andl $-65536, %esi # imm = 0xFFFF0000
70 ; CHECK-BMI-NEXT: orl %esi, %eax
71 ; CHECK-BMI-NEXT: retq
72 %mx = and i32 %x, 65535
73 %my = and i32 %y, -65536
78 define i64 @out64_constmask(i64 %x, i64 %y) {
79 ; CHECK-NOBMI-LABEL: out64_constmask:
80 ; CHECK-NOBMI: # %bb.0:
81 ; CHECK-NOBMI-NEXT: movl %edi, %ecx
82 ; CHECK-NOBMI-NEXT: movabsq $-4294967296, %rax # imm = 0xFFFFFFFF00000000
83 ; CHECK-NOBMI-NEXT: andq %rsi, %rax
84 ; CHECK-NOBMI-NEXT: orq %rcx, %rax
85 ; CHECK-NOBMI-NEXT: retq
87 ; CHECK-BMI-LABEL: out64_constmask:
89 ; CHECK-BMI-NEXT: movl %edi, %ecx
90 ; CHECK-BMI-NEXT: movabsq $-4294967296, %rax # imm = 0xFFFFFFFF00000000
91 ; CHECK-BMI-NEXT: andq %rsi, %rax
92 ; CHECK-BMI-NEXT: orq %rcx, %rax
93 ; CHECK-BMI-NEXT: retq
94 %mx = and i64 %x, 4294967295
95 %my = and i64 %y, -4294967296
100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
101 ; Should be the same as the previous one.
102 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
104 define i8 @in8_constmask(i8 %x, i8 %y) {
105 ; CHECK-NOBMI-LABEL: in8_constmask:
106 ; CHECK-NOBMI: # %bb.0:
107 ; CHECK-NOBMI-NEXT: movl %esi, %eax
108 ; CHECK-NOBMI-NEXT: xorl %esi, %edi
109 ; CHECK-NOBMI-NEXT: andb $15, %dil
110 ; CHECK-NOBMI-NEXT: xorb %dil, %al
111 ; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax
112 ; CHECK-NOBMI-NEXT: retq
114 ; CHECK-BMI-LABEL: in8_constmask:
115 ; CHECK-BMI: # %bb.0:
116 ; CHECK-BMI-NEXT: movl %esi, %eax
117 ; CHECK-BMI-NEXT: xorl %esi, %edi
118 ; CHECK-BMI-NEXT: andb $15, %dil
119 ; CHECK-BMI-NEXT: xorb %dil, %al
120 ; CHECK-BMI-NEXT: # kill: def $al killed $al killed $eax
121 ; CHECK-BMI-NEXT: retq
128 define i16 @in16_constmask(i16 %x, i16 %y) {
129 ; CHECK-NOBMI-LABEL: in16_constmask:
130 ; CHECK-NOBMI: # %bb.0:
131 ; CHECK-NOBMI-NEXT: xorl %esi, %edi
132 ; CHECK-NOBMI-NEXT: movzbl %dil, %eax
133 ; CHECK-NOBMI-NEXT: xorl %esi, %eax
134 ; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax
135 ; CHECK-NOBMI-NEXT: retq
137 ; CHECK-BMI-LABEL: in16_constmask:
138 ; CHECK-BMI: # %bb.0:
139 ; CHECK-BMI-NEXT: xorl %esi, %edi
140 ; CHECK-BMI-NEXT: movzbl %dil, %eax
141 ; CHECK-BMI-NEXT: xorl %esi, %eax
142 ; CHECK-BMI-NEXT: # kill: def $ax killed $ax killed $eax
143 ; CHECK-BMI-NEXT: retq
145 %n1 = and i16 %n0, 255
150 define i32 @in32_constmask(i32 %x, i32 %y) {
151 ; CHECK-NOBMI-LABEL: in32_constmask:
152 ; CHECK-NOBMI: # %bb.0:
153 ; CHECK-NOBMI-NEXT: xorl %esi, %edi
154 ; CHECK-NOBMI-NEXT: movzwl %di, %eax
155 ; CHECK-NOBMI-NEXT: xorl %esi, %eax
156 ; CHECK-NOBMI-NEXT: retq
158 ; CHECK-BMI-LABEL: in32_constmask:
159 ; CHECK-BMI: # %bb.0:
160 ; CHECK-BMI-NEXT: xorl %esi, %edi
161 ; CHECK-BMI-NEXT: movzwl %di, %eax
162 ; CHECK-BMI-NEXT: xorl %esi, %eax
163 ; CHECK-BMI-NEXT: retq
165 %n1 = and i32 %n0, 65535
170 define i64 @in64_constmask(i64 %x, i64 %y) {
171 ; CHECK-NOBMI-LABEL: in64_constmask:
172 ; CHECK-NOBMI: # %bb.0:
173 ; CHECK-NOBMI-NEXT: movl %esi, %eax
174 ; CHECK-NOBMI-NEXT: xorl %edi, %eax
175 ; CHECK-NOBMI-NEXT: xorq %rsi, %rax
176 ; CHECK-NOBMI-NEXT: retq
178 ; CHECK-BMI-LABEL: in64_constmask:
179 ; CHECK-BMI: # %bb.0:
180 ; CHECK-BMI-NEXT: movl %esi, %eax
181 ; CHECK-BMI-NEXT: xorl %edi, %eax
182 ; CHECK-BMI-NEXT: xorq %rsi, %rax
183 ; CHECK-BMI-NEXT: retq
185 %n1 = and i64 %n0, 4294967295
190 ; ============================================================================ ;
191 ; Constant Commutativity tests.
192 ; ============================================================================ ;
194 define i32 @in_constmask_commutativity_0_1(i32 %x, i32 %y) {
195 ; CHECK-NOBMI-LABEL: in_constmask_commutativity_0_1:
196 ; CHECK-NOBMI: # %bb.0:
197 ; CHECK-NOBMI-NEXT: xorl %esi, %edi
198 ; CHECK-NOBMI-NEXT: movzwl %di, %eax
199 ; CHECK-NOBMI-NEXT: xorl %esi, %eax
200 ; CHECK-NOBMI-NEXT: retq
202 ; CHECK-BMI-LABEL: in_constmask_commutativity_0_1:
203 ; CHECK-BMI: # %bb.0:
204 ; CHECK-BMI-NEXT: xorl %esi, %edi
205 ; CHECK-BMI-NEXT: movzwl %di, %eax
206 ; CHECK-BMI-NEXT: xorl %esi, %eax
207 ; CHECK-BMI-NEXT: retq
209 %n1 = and i32 %n0, 65535
210 %r = xor i32 %y, %n1 ; swapped
214 define i32 @in_constmask_commutativity_1_0(i32 %x, i32 %y) {
215 ; CHECK-NOBMI-LABEL: in_constmask_commutativity_1_0:
216 ; CHECK-NOBMI: # %bb.0:
217 ; CHECK-NOBMI-NEXT: xorl %edi, %esi
218 ; CHECK-NOBMI-NEXT: movzwl %si, %eax
219 ; CHECK-NOBMI-NEXT: xorl %edi, %eax
220 ; CHECK-NOBMI-NEXT: retq
222 ; CHECK-BMI-LABEL: in_constmask_commutativity_1_0:
223 ; CHECK-BMI: # %bb.0:
224 ; CHECK-BMI-NEXT: xorl %edi, %esi
225 ; CHECK-BMI-NEXT: movzwl %si, %eax
226 ; CHECK-BMI-NEXT: xorl %edi, %eax
227 ; CHECK-BMI-NEXT: retq
229 %n1 = and i32 %n0, 65535
230 %r = xor i32 %n1, %x ; %x instead of %y
234 define i32 @in_constmask_commutativity_1_1(i32 %x, i32 %y) {
235 ; CHECK-NOBMI-LABEL: in_constmask_commutativity_1_1:
236 ; CHECK-NOBMI: # %bb.0:
237 ; CHECK-NOBMI-NEXT: xorl %edi, %esi
238 ; CHECK-NOBMI-NEXT: movzwl %si, %eax
239 ; CHECK-NOBMI-NEXT: xorl %edi, %eax
240 ; CHECK-NOBMI-NEXT: retq
242 ; CHECK-BMI-LABEL: in_constmask_commutativity_1_1:
243 ; CHECK-BMI: # %bb.0:
244 ; CHECK-BMI-NEXT: xorl %edi, %esi
245 ; CHECK-BMI-NEXT: movzwl %si, %eax
246 ; CHECK-BMI-NEXT: xorl %edi, %eax
247 ; CHECK-BMI-NEXT: retq
249 %n1 = and i32 %n0, 65535
250 %r = xor i32 %x, %n1 ; swapped, %x instead of %y
254 ; ============================================================================ ;
256 ; ============================================================================ ;
258 define i32 @in_complex_y0_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
259 ; CHECK-NOBMI-LABEL: in_complex_y0_constmask:
260 ; CHECK-NOBMI: # %bb.0:
261 ; CHECK-NOBMI-NEXT: andl %edx, %esi
262 ; CHECK-NOBMI-NEXT: xorl %esi, %edi
263 ; CHECK-NOBMI-NEXT: movzwl %di, %eax
264 ; CHECK-NOBMI-NEXT: xorl %esi, %eax
265 ; CHECK-NOBMI-NEXT: retq
267 ; CHECK-BMI-LABEL: in_complex_y0_constmask:
268 ; CHECK-BMI: # %bb.0:
269 ; CHECK-BMI-NEXT: andl %edx, %esi
270 ; CHECK-BMI-NEXT: xorl %esi, %edi
271 ; CHECK-BMI-NEXT: movzwl %di, %eax
272 ; CHECK-BMI-NEXT: xorl %esi, %eax
273 ; CHECK-BMI-NEXT: retq
274 %y = and i32 %y_hi, %y_low
276 %n1 = and i32 %n0, 65535
281 define i32 @in_complex_y1_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
282 ; CHECK-NOBMI-LABEL: in_complex_y1_constmask:
283 ; CHECK-NOBMI: # %bb.0:
284 ; CHECK-NOBMI-NEXT: andl %edx, %esi
285 ; CHECK-NOBMI-NEXT: xorl %esi, %edi
286 ; CHECK-NOBMI-NEXT: movzwl %di, %eax
287 ; CHECK-NOBMI-NEXT: xorl %esi, %eax
288 ; CHECK-NOBMI-NEXT: retq
290 ; CHECK-BMI-LABEL: in_complex_y1_constmask:
291 ; CHECK-BMI: # %bb.0:
292 ; CHECK-BMI-NEXT: andl %edx, %esi
293 ; CHECK-BMI-NEXT: xorl %esi, %edi
294 ; CHECK-BMI-NEXT: movzwl %di, %eax
295 ; CHECK-BMI-NEXT: xorl %esi, %eax
296 ; CHECK-BMI-NEXT: retq
297 %y = and i32 %y_hi, %y_low
299 %n1 = and i32 %n0, 65535
304 ; ============================================================================ ;
305 ; Negative tests. Should not be folded.
306 ; ============================================================================ ;
310 declare void @use32(i32) nounwind
312 define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
313 ; CHECK-NOBMI-LABEL: in_multiuse_A_constmask:
314 ; CHECK-NOBMI: # %bb.0:
315 ; CHECK-NOBMI-NEXT: pushq %rbp
316 ; CHECK-NOBMI-NEXT: pushq %rbx
317 ; CHECK-NOBMI-NEXT: pushq %rax
318 ; CHECK-NOBMI-NEXT: movl %esi, %ebx
319 ; CHECK-NOBMI-NEXT: xorl %esi, %edi
320 ; CHECK-NOBMI-NEXT: movzwl %di, %ebp
321 ; CHECK-NOBMI-NEXT: movl %ebp, %edi
322 ; CHECK-NOBMI-NEXT: callq use32
323 ; CHECK-NOBMI-NEXT: xorl %ebx, %ebp
324 ; CHECK-NOBMI-NEXT: movl %ebp, %eax
325 ; CHECK-NOBMI-NEXT: addq $8, %rsp
326 ; CHECK-NOBMI-NEXT: popq %rbx
327 ; CHECK-NOBMI-NEXT: popq %rbp
328 ; CHECK-NOBMI-NEXT: retq
330 ; CHECK-BMI-LABEL: in_multiuse_A_constmask:
331 ; CHECK-BMI: # %bb.0:
332 ; CHECK-BMI-NEXT: pushq %rbp
333 ; CHECK-BMI-NEXT: pushq %rbx
334 ; CHECK-BMI-NEXT: pushq %rax
335 ; CHECK-BMI-NEXT: movl %esi, %ebx
336 ; CHECK-BMI-NEXT: xorl %esi, %edi
337 ; CHECK-BMI-NEXT: movzwl %di, %ebp
338 ; CHECK-BMI-NEXT: movl %ebp, %edi
339 ; CHECK-BMI-NEXT: callq use32
340 ; CHECK-BMI-NEXT: xorl %ebx, %ebp
341 ; CHECK-BMI-NEXT: movl %ebp, %eax
342 ; CHECK-BMI-NEXT: addq $8, %rsp
343 ; CHECK-BMI-NEXT: popq %rbx
344 ; CHECK-BMI-NEXT: popq %rbp
345 ; CHECK-BMI-NEXT: retq
347 %n1 = and i32 %n0, 65535
348 call void @use32(i32 %n1)
353 define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {
354 ; CHECK-NOBMI-LABEL: in_multiuse_B_constmask:
355 ; CHECK-NOBMI: # %bb.0:
356 ; CHECK-NOBMI-NEXT: pushq %rbp
357 ; CHECK-NOBMI-NEXT: pushq %rbx
358 ; CHECK-NOBMI-NEXT: pushq %rax
359 ; CHECK-NOBMI-NEXT: movl %esi, %ebx
360 ; CHECK-NOBMI-NEXT: xorl %esi, %edi
361 ; CHECK-NOBMI-NEXT: movzwl %di, %ebp
362 ; CHECK-NOBMI-NEXT: callq use32
363 ; CHECK-NOBMI-NEXT: xorl %ebx, %ebp
364 ; CHECK-NOBMI-NEXT: movl %ebp, %eax
365 ; CHECK-NOBMI-NEXT: addq $8, %rsp
366 ; CHECK-NOBMI-NEXT: popq %rbx
367 ; CHECK-NOBMI-NEXT: popq %rbp
368 ; CHECK-NOBMI-NEXT: retq
370 ; CHECK-BMI-LABEL: in_multiuse_B_constmask:
371 ; CHECK-BMI: # %bb.0:
372 ; CHECK-BMI-NEXT: pushq %rbp
373 ; CHECK-BMI-NEXT: pushq %rbx
374 ; CHECK-BMI-NEXT: pushq %rax
375 ; CHECK-BMI-NEXT: movl %esi, %ebx
376 ; CHECK-BMI-NEXT: xorl %esi, %edi
377 ; CHECK-BMI-NEXT: movzwl %di, %ebp
378 ; CHECK-BMI-NEXT: callq use32
379 ; CHECK-BMI-NEXT: xorl %ebx, %ebp
380 ; CHECK-BMI-NEXT: movl %ebp, %eax
381 ; CHECK-BMI-NEXT: addq $8, %rsp
382 ; CHECK-BMI-NEXT: popq %rbx
383 ; CHECK-BMI-NEXT: popq %rbp
384 ; CHECK-BMI-NEXT: retq
386 %n1 = and i32 %n0, 65535
387 call void @use32(i32 %n0)
392 ; Various bad variants
394 define i32 @n0_badconstmask(i32 %x, i32 %y) {
395 ; CHECK-NOBMI-LABEL: n0_badconstmask:
396 ; CHECK-NOBMI: # %bb.0:
397 ; CHECK-NOBMI-NEXT: movzwl %di, %eax
398 ; CHECK-NOBMI-NEXT: andl $-65535, %esi # imm = 0xFFFF0001
399 ; CHECK-NOBMI-NEXT: orl %esi, %eax
400 ; CHECK-NOBMI-NEXT: retq
402 ; CHECK-BMI-LABEL: n0_badconstmask:
403 ; CHECK-BMI: # %bb.0:
404 ; CHECK-BMI-NEXT: movzwl %di, %eax
405 ; CHECK-BMI-NEXT: andl $-65535, %esi # imm = 0xFFFF0001
406 ; CHECK-BMI-NEXT: orl %esi, %eax
407 ; CHECK-BMI-NEXT: retq
408 %mx = and i32 %x, 65535
409 %my = and i32 %y, -65535 ; instead of -65536
414 define i32 @n1_thirdvar_constmask(i32 %x, i32 %y, i32 %z) {
415 ; CHECK-NOBMI-LABEL: n1_thirdvar_constmask:
416 ; CHECK-NOBMI: # %bb.0:
417 ; CHECK-NOBMI-NEXT: xorl %esi, %edi
418 ; CHECK-NOBMI-NEXT: movzwl %di, %eax
419 ; CHECK-NOBMI-NEXT: xorl %edx, %eax
420 ; CHECK-NOBMI-NEXT: retq
422 ; CHECK-BMI-LABEL: n1_thirdvar_constmask:
423 ; CHECK-BMI: # %bb.0:
424 ; CHECK-BMI-NEXT: xorl %esi, %edi
425 ; CHECK-BMI-NEXT: movzwl %di, %eax
426 ; CHECK-BMI-NEXT: xorl %edx, %eax
427 ; CHECK-BMI-NEXT: retq
429 %n1 = and i32 %n0, 65535
430 %r = xor i32 %n1, %z ; instead of %y