1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=x86_64-- < %s | FileCheck %s
4 declare i8 @llvm.fshl.i8(i8, i8, i8)
5 declare i32 @llvm.fshl.i32(i32, i32, i32)
6 declare i16 @llvm.fshr.i16(i16, i16, i16)
7 declare i64 @llvm.fshr.i64(i64, i64, i64)
8 declare <4 x i32> @llvm.fshl.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
9 declare void @use16(i16)
10 declare void @use32(i32)
12 define i1 @rotl_eq_0(i8 %x, i8 %y) nounwind {
13 ; CHECK-LABEL: rotl_eq_0:
15 ; CHECK-NEXT: testb %dil, %dil
16 ; CHECK-NEXT: sete %al
18 %rot = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %y)
19 %r = icmp eq i8 %rot, 0
25 define i1 @rotl_ne_0(i32 %x, i32 %y) nounwind {
26 ; CHECK-LABEL: rotl_ne_0:
28 ; CHECK-NEXT: pushq %rbx
29 ; CHECK-NEXT: movl %esi, %ecx
30 ; CHECK-NEXT: movl %edi, %ebx
31 ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
32 ; CHECK-NEXT: roll %cl, %edi
33 ; CHECK-NEXT: callq use32@PLT
34 ; CHECK-NEXT: testl %ebx, %ebx
35 ; CHECK-NEXT: setne %al
36 ; CHECK-NEXT: popq %rbx
38 %rot = tail call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %y)
39 call void @use32(i32 %rot)
40 %r = icmp ne i32 %rot, 0
44 define i1 @rotl_eq_n1(i8 %x, i8 %y) nounwind {
45 ; CHECK-LABEL: rotl_eq_n1:
47 ; CHECK-NEXT: cmpb $-1, %dil
48 ; CHECK-NEXT: sete %al
50 %rot = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %y)
51 %r = icmp eq i8 %rot, -1
57 define <4 x i1> @rotl_ne_n1(<4 x i32> %x, <4 x i32> %y) nounwind {
58 ; CHECK-LABEL: rotl_ne_n1:
60 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1
61 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm0
62 ; CHECK-NEXT: pxor %xmm1, %xmm0
64 %rot = tail call <4 x i32> @llvm.fshl.v4i32(<4 x i32>%x, <4 x i32> %x, <4 x i32> %y)
65 %r = icmp ne <4 x i32> %rot, <i32 -1, i32 -1, i32 -1, i32 -1>
69 ; Undef is ok to propagate.
71 define <4 x i1> @rotl_ne_n1_undef(<4 x i32> %x, <4 x i32> %y) nounwind {
72 ; CHECK-LABEL: rotl_ne_n1_undef:
74 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1
75 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm0
76 ; CHECK-NEXT: pxor %xmm1, %xmm0
78 %rot = tail call <4 x i32> @llvm.fshl.v4i32(<4 x i32>%x, <4 x i32> %x, <4 x i32> %y)
79 %r = icmp ne <4 x i32> %rot, <i32 -1, i32 undef, i32 -1, i32 -1>
83 define i1 @rotr_eq_0(i16 %x, i16 %y) nounwind {
84 ; CHECK-LABEL: rotr_eq_0:
86 ; CHECK-NEXT: pushq %rbx
87 ; CHECK-NEXT: movl %esi, %ecx
88 ; CHECK-NEXT: movl %edi, %ebx
89 ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
90 ; CHECK-NEXT: rorw %cl, %di
91 ; CHECK-NEXT: callq use16@PLT
92 ; CHECK-NEXT: testw %bx, %bx
93 ; CHECK-NEXT: sete %al
94 ; CHECK-NEXT: popq %rbx
96 %rot = tail call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 %y)
97 call void @use16(i16 %rot)
98 %r = icmp eq i16 %rot, 0
102 define i1 @rotr_ne_0(i64 %x, i64 %y) nounwind {
103 ; CHECK-LABEL: rotr_ne_0:
105 ; CHECK-NEXT: testq %rdi, %rdi
106 ; CHECK-NEXT: setne %al
108 %rot = tail call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %y)
109 %r = icmp ne i64 %rot, 0
113 define i1 @rotr_eq_n1(i64 %x, i64 %y) nounwind {
114 ; CHECK-LABEL: rotr_eq_n1:
116 ; CHECK-NEXT: cmpq $-1, %rdi
117 ; CHECK-NEXT: sete %al
119 %rot = tail call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %y)
120 %r = icmp eq i64 %rot, -1
124 define i1 @rotr_ne_n1(i16 %x, i16 %y) nounwind {
125 ; CHECK-LABEL: rotr_ne_n1:
127 ; CHECK-NEXT: cmpw $-1, %di
128 ; CHECK-NEXT: setne %al
130 %rot = tail call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 %y)
131 %r = icmp ne i16 %rot, -1
135 ; negative test - wrong constant value
137 define i1 @rotr_ne_1(i64 %x, i64 %y) nounwind {
138 ; CHECK-LABEL: rotr_ne_1:
140 ; CHECK-NEXT: movq %rsi, %rcx
141 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
142 ; CHECK-NEXT: rorq %cl, %rdi
143 ; CHECK-NEXT: cmpq $1, %rdi
144 ; CHECK-NEXT: setne %al
146 %rot = tail call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %y)
147 %r = icmp ne i64 %rot, 1
151 ; negative test - wrong predicate
153 define i1 @rotr_sgt_n1(i16 %x, i16 %y) nounwind {
154 ; CHECK-LABEL: rotr_sgt_n1:
156 ; CHECK-NEXT: movl %esi, %ecx
157 ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
158 ; CHECK-NEXT: rorw %cl, %di
159 ; CHECK-NEXT: testw %di, %di
160 ; CHECK-NEXT: setns %al
162 %rot = tail call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 %y)
163 %r = icmp sgt i16 %rot, -1
167 ; negative test - must be a rotate, not general funnel shift
169 define i1 @fshl_eq_n1(i8 %x, i8 %y, i8 %z) nounwind {
170 ; CHECK-LABEL: fshl_eq_n1:
172 ; CHECK-NEXT: movl %edx, %ecx
173 ; CHECK-NEXT: shll $8, %edi
174 ; CHECK-NEXT: movzbl %sil, %eax
175 ; CHECK-NEXT: orl %edi, %eax
176 ; CHECK-NEXT: andb $7, %cl
177 ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
178 ; CHECK-NEXT: shll %cl, %eax
179 ; CHECK-NEXT: shrl $8, %eax
180 ; CHECK-NEXT: cmpb $-1, %al
181 ; CHECK-NEXT: sete %al
183 %fsh = tail call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 %z)
184 %r = icmp eq i8 %fsh, -1
188 define i1 @or_rotl_eq_0(i8 %x, i8 %y, i8 %z) nounwind {
189 ; CHECK-LABEL: or_rotl_eq_0:
191 ; CHECK-NEXT: orb %sil, %dil
192 ; CHECK-NEXT: sete %al
194 %rot = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
196 %r = icmp eq i8 %or, 0
200 define i1 @or_rotr_ne_0(i64 %x, i64 %y, i64 %z) nounwind {
201 ; CHECK-LABEL: or_rotr_ne_0:
203 ; CHECK-NEXT: orq %rsi, %rdi
204 ; CHECK-NEXT: setne %al
206 %rot = tail call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %z)
207 %or = or i64 %y, %rot
208 %r = icmp ne i64 %or, 0
212 ; negative test - wrong constant
214 define i1 @or_rotl_ne_n1(i32 %x, i32 %y, i32 %z) nounwind {
215 ; CHECK-LABEL: or_rotl_ne_n1:
217 ; CHECK-NEXT: movl %edx, %ecx
218 ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
219 ; CHECK-NEXT: roll %cl, %edi
220 ; CHECK-NEXT: orl %esi, %edi
221 ; CHECK-NEXT: cmpl $-1, %edi
222 ; CHECK-NEXT: setne %al
224 %rot = tail call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %z)
225 %or = or i32 %y, %rot
226 %r = icmp ne i32 %or, -1
230 ; negative test - extra use
232 define i1 @or_rotl_ne_0_use(i32 %x, i32 %y, i32 %z) nounwind {
233 ; CHECK-LABEL: or_rotl_ne_0_use:
235 ; CHECK-NEXT: pushq %rbx
236 ; CHECK-NEXT: movl %edx, %ecx
237 ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
238 ; CHECK-NEXT: roll %cl, %edi
239 ; CHECK-NEXT: orl %esi, %edi
240 ; CHECK-NEXT: setne %bl
241 ; CHECK-NEXT: callq use32@PLT
242 ; CHECK-NEXT: movl %ebx, %eax
243 ; CHECK-NEXT: popq %rbx
245 %rot = tail call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %z)
246 %or = or i32 %y, %rot
247 call void @use32(i32 %or)
248 %r = icmp ne i32 %or, 0
252 define <4 x i1> @or_rotl_ne_eq0(<4 x i32> %x, <4 x i32> %y) nounwind {
253 ; CHECK-LABEL: or_rotl_ne_eq0:
255 ; CHECK-NEXT: pxor %xmm2, %xmm2
256 ; CHECK-NEXT: por %xmm1, %xmm0
257 ; CHECK-NEXT: pcmpeqd %xmm2, %xmm0
259 %rot = tail call <4 x i32> @llvm.fshl.v4i32(<4 x i32>%x, <4 x i32> %x, <4 x i32> %y)
260 %or = or <4 x i32> %y, %rot
261 %r = icmp eq <4 x i32> %or, <i32 0, i32 0, i32 0, i32 poison>
265 define i1 @fshl_or_eq_0(i32 %x, i32 %y) {
266 ; CHECK-LABEL: fshl_or_eq_0:
268 ; CHECK-NEXT: shll $5, %esi
269 ; CHECK-NEXT: orl %edi, %esi
270 ; CHECK-NEXT: sete %al
273 %f = call i32 @llvm.fshl.i32(i32 %or, i32 %x, i32 5)
274 %r = icmp eq i32 %f, 0
278 define i1 @fshl_or_commute_eq_0(i32 %x, i32 %y) {
279 ; CHECK-LABEL: fshl_or_commute_eq_0:
281 ; CHECK-NEXT: shll $5, %esi
282 ; CHECK-NEXT: orl %edi, %esi
283 ; CHECK-NEXT: sete %al
286 %f = call i32 @llvm.fshl.i32(i32 %or, i32 %x, i32 5)
287 %r = icmp eq i32 %f, 0
291 define <4 x i1> @fshl_or2_eq_0(<4 x i32> %x, <4 x i32> %y) {
292 ; CHECK-LABEL: fshl_or2_eq_0:
294 ; CHECK-NEXT: pxor %xmm2, %xmm2
295 ; CHECK-NEXT: psrld $7, %xmm1
296 ; CHECK-NEXT: por %xmm1, %xmm0
297 ; CHECK-NEXT: pcmpeqd %xmm2, %xmm0
299 %or = or <4 x i32> %x, %y
300 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %or, <4 x i32> <i32 25, i32 25, i32 25, i32 25>)
301 %r = icmp eq <4 x i32> %f, zeroinitializer
305 define <4 x i1> @fshl_or2_commute_eq_0(<4 x i32> %x, <4 x i32> %y) {
306 ; CHECK-LABEL: fshl_or2_commute_eq_0:
308 ; CHECK-NEXT: pxor %xmm2, %xmm2
309 ; CHECK-NEXT: psrld $7, %xmm1
310 ; CHECK-NEXT: por %xmm1, %xmm0
311 ; CHECK-NEXT: pcmpeqd %xmm2, %xmm0
313 %or = or <4 x i32> %y, %x
314 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %or, <4 x i32> <i32 25, i32 25, i32 25, i32 25>)
315 %r = icmp eq <4 x i32> %f, zeroinitializer
319 define i1 @fshr_or_eq_0(i16 %x, i16 %y) {
320 ; CHECK-LABEL: fshr_or_eq_0:
322 ; CHECK-NEXT: shll $8, %esi
323 ; CHECK-NEXT: orw %di, %si
324 ; CHECK-NEXT: sete %al
327 %f = call i16 @llvm.fshr.i16(i16 %or, i16 %x, i16 8)
328 %r = icmp eq i16 %f, 0
332 define i1 @fshr_or_commute_eq_0(i16 %x, i16 %y) {
333 ; CHECK-LABEL: fshr_or_commute_eq_0:
335 ; CHECK-NEXT: shll $8, %esi
336 ; CHECK-NEXT: orw %di, %si
337 ; CHECK-NEXT: sete %al
340 %f = call i16 @llvm.fshr.i16(i16 %or, i16 %x, i16 8)
341 %r = icmp eq i16 %f, 0
345 define i1 @fshr_or2_eq_0(i64 %x, i64 %y) {
346 ; CHECK-LABEL: fshr_or2_eq_0:
348 ; CHECK-NEXT: shrq $3, %rsi
349 ; CHECK-NEXT: orq %rdi, %rsi
350 ; CHECK-NEXT: sete %al
353 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %or, i64 3)
354 %r = icmp eq i64 %f, 0
358 define i1 @fshr_or2_commute_eq_0(i64 %x, i64 %y) {
359 ; CHECK-LABEL: fshr_or2_commute_eq_0:
361 ; CHECK-NEXT: shrq $3, %rsi
362 ; CHECK-NEXT: orq %rdi, %rsi
363 ; CHECK-NEXT: sete %al
366 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %or, i64 3)
367 %r = icmp eq i64 %f, 0
371 define i1 @fshl_or_ne_0(i32 %x, i32 %y) {
372 ; CHECK-LABEL: fshl_or_ne_0:
374 ; CHECK-NEXT: shll $7, %esi
375 ; CHECK-NEXT: orl %edi, %esi
376 ; CHECK-NEXT: setne %al
379 %f = call i32 @llvm.fshl.i32(i32 %or, i32 %x, i32 7)
380 %r = icmp ne i32 %f, 0
384 define i1 @fshl_or_commute_ne_0(i32 %x, i32 %y) {
385 ; CHECK-LABEL: fshl_or_commute_ne_0:
387 ; CHECK-NEXT: shll $7, %esi
388 ; CHECK-NEXT: orl %edi, %esi
389 ; CHECK-NEXT: setne %al
392 %f = call i32 @llvm.fshl.i32(i32 %or, i32 %x, i32 7)
393 %r = icmp ne i32 %f, 0
397 define <4 x i1> @fshl_or2_ne_0(<4 x i32> %x, <4 x i32> %y) {
398 ; CHECK-LABEL: fshl_or2_ne_0:
400 ; CHECK-NEXT: pxor %xmm2, %xmm2
401 ; CHECK-NEXT: psrld $27, %xmm1
402 ; CHECK-NEXT: por %xmm1, %xmm0
403 ; CHECK-NEXT: pcmpeqd %xmm2, %xmm0
404 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1
405 ; CHECK-NEXT: pxor %xmm1, %xmm0
407 %or = or <4 x i32> %x, %y
408 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %or, <4 x i32> <i32 5, i32 5, i32 5, i32 5>)
409 %r = icmp ne <4 x i32> %f, zeroinitializer
413 define <4 x i1> @fshl_or2_commute_ne_0(<4 x i32> %x, <4 x i32> %y) {
414 ; CHECK-LABEL: fshl_or2_commute_ne_0:
416 ; CHECK-NEXT: pxor %xmm2, %xmm2
417 ; CHECK-NEXT: psrld $27, %xmm1
418 ; CHECK-NEXT: por %xmm1, %xmm0
419 ; CHECK-NEXT: pcmpeqd %xmm2, %xmm0
420 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1
421 ; CHECK-NEXT: pxor %xmm1, %xmm0
423 %or = or <4 x i32> %y, %x
424 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %or, <4 x i32> <i32 5, i32 5, i32 5, i32 5>)
425 %r = icmp ne <4 x i32> %f, zeroinitializer
429 define i1 @fshr_or_ne_0(i64 %x, i64 %y) {
430 ; CHECK-LABEL: fshr_or_ne_0:
432 ; CHECK-NEXT: shlq $63, %rsi
433 ; CHECK-NEXT: orq %rdi, %rsi
434 ; CHECK-NEXT: setne %al
437 %f = call i64 @llvm.fshr.i64(i64 %or, i64 %x, i64 1)
438 %r = icmp ne i64 %f, 0
442 define i1 @fshr_or_commute_ne_0(i64 %x, i64 %y) {
443 ; CHECK-LABEL: fshr_or_commute_ne_0:
445 ; CHECK-NEXT: shlq $63, %rsi
446 ; CHECK-NEXT: orq %rdi, %rsi
447 ; CHECK-NEXT: setne %al
450 %f = call i64 @llvm.fshr.i64(i64 %or, i64 %x, i64 1)
451 %r = icmp ne i64 %f, 0
455 define i1 @fshr_or2_ne_0(i16 %x, i16 %y) {
456 ; CHECK-LABEL: fshr_or2_ne_0:
458 ; CHECK-NEXT: movzwl %si, %eax
459 ; CHECK-NEXT: shrl $2, %eax
460 ; CHECK-NEXT: orw %di, %ax
461 ; CHECK-NEXT: setne %al
464 %f = call i16 @llvm.fshr.i16(i16 %x, i16 %or, i16 2)
465 %r = icmp ne i16 %f, 0
469 define i1 @fshr_or2_commute_ne_0(i16 %x, i16 %y) {
470 ; CHECK-LABEL: fshr_or2_commute_ne_0:
472 ; CHECK-NEXT: movzwl %si, %eax
473 ; CHECK-NEXT: shrl $2, %eax
474 ; CHECK-NEXT: orw %di, %ax
475 ; CHECK-NEXT: setne %al
478 %f = call i16 @llvm.fshr.i16(i16 %x, i16 %or, i16 2)
479 %r = icmp ne i16 %f, 0
483 define i1 @fshl_xor_eq_0(i32 %x, i32 %y) {
484 ; CHECK-LABEL: fshl_xor_eq_0:
486 ; CHECK-NEXT: xorl %edi, %esi
487 ; CHECK-NEXT: shldl $2, %edi, %esi
488 ; CHECK-NEXT: sete %al
491 %f = call i32 @llvm.fshl.i32(i32 %or, i32 %x, i32 2)
492 %r = icmp eq i32 %f, 0
496 define i1 @fshl_or_sgt_0(i32 %x, i32 %y) {
497 ; CHECK-LABEL: fshl_or_sgt_0:
499 ; CHECK-NEXT: orl %edi, %esi
500 ; CHECK-NEXT: shldl $2, %edi, %esi
501 ; CHECK-NEXT: testl %esi, %esi
502 ; CHECK-NEXT: setg %al
505 %f = call i32 @llvm.fshl.i32(i32 %or, i32 %x, i32 2)
506 %r = icmp sgt i32 %f, 0
510 define i1 @fshl_or_ne_2(i32 %x, i32 %y) {
511 ; CHECK-LABEL: fshl_or_ne_2:
513 ; CHECK-NEXT: orl %edi, %esi
514 ; CHECK-NEXT: shldl $2, %edi, %esi
515 ; CHECK-NEXT: cmpl $2, %esi
516 ; CHECK-NEXT: setne %al
519 %f = call i32 @llvm.fshl.i32(i32 %or, i32 %x, i32 2)
520 %r = icmp ne i32 %f, 2