Files
clang-p2996/llvm/test/CodeGen/X86/select.ll
Matt Arsenault 4a36e96c3f RegAllocGreedy: Account for reserved registers in num regs heuristic
This simple heuristic uses the estimated live range length combined
with the number of registers in the class to switch which heuristic to
use. This was taking the raw number of registers in the class, even
though not all of them may be available. AMDGPU heavily relies on
dynamically reserved numbers of registers based on user attributes to
satisfy occupancy constraints, so the raw number is highly misleading.

There are still a few problems here. In the original testcase that
made me notice this, the live range size is incorrect after the
scheduler rearranges instructions, since the instructions don't have
the original InstrDist offsets. Additionally, I think it would be more
appropriate to use the number of disjointly allocatable registers in
the class. For the AMDGPU register tuples, there are a large number of
registers in each tuple class, but only a small fraction can actually
be allocated at the same time since they all overlap with each
other. It seems we do not have a query that corresponds to the number
of independently allocatable registers. Relatedly, I'm still debugging
some allocation failures where overlapping tuples seem to not be
handled correctly.

The test changes are mostly noise. There are a handful of x86 tests
that look like regressions with an additional spill, and a handful
that now avoid a spill. The worst looking regression is likely
test/Thumb2/mve-vld4.ll which introduces a few additional
spills. test/CodeGen/AMDGPU/soft-clause-exceeds-register-budget.ll
shows a massive improvement by completely eliminating a large number
of spills inside a loop.
2021-09-14 21:00:29 -04:00

1696 lines
50 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-apple-darwin10 | FileCheck %s --check-prefix=CHECK --check-prefix=GENERIC
; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -mcpu=atom | FileCheck %s --check-prefix=CHECK --check-prefix=ATOM
; RUN: llc < %s -mtriple=i386-apple-darwin10 -mcpu=athlon | FileCheck %s --check-prefix=ATHLON
; RUN: llc < %s -mtriple=i386-intel-elfiamcu | FileCheck %s --check-prefix=MCU
; PR5757
%0 = type { i64, i32 }
define i32 @test1(%0* %p, %0* %q, i1 %r) nounwind {
; GENERIC-LABEL: test1:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: testb $1, %dl
; GENERIC-NEXT: cmoveq %rsi, %rdi
; GENERIC-NEXT: movl 8(%rdi), %eax
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test1:
; ATOM: ## %bb.0:
; ATOM-NEXT: testb $1, %dl
; ATOM-NEXT: cmoveq %rsi, %rdi
; ATOM-NEXT: movl 8(%rdi), %eax
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test1:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: cmovnel %eax, %ecx
; ATHLON-NEXT: movl (%ecx), %eax
; ATHLON-NEXT: movl 8(%eax), %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: test1:
; MCU: # %bb.0:
; MCU-NEXT: testb $1, %cl
; MCU-NEXT: jne .LBB0_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: movl %edx, %eax
; MCU-NEXT: .LBB0_2:
; MCU-NEXT: movl 8(%eax), %eax
; MCU-NEXT: retl
%t0 = load %0, %0* %p
%t1 = load %0, %0* %q
%t4 = select i1 %r, %0 %t0, %0 %t1
%t5 = extractvalue %0 %t4, 1
ret i32 %t5
}
; PR2139
define i32 @test2() nounwind {
; GENERIC-LABEL: test2:
; GENERIC: ## %bb.0: ## %entry
; GENERIC-NEXT: pushq %rax
; GENERIC-NEXT: callq _return_false
; GENERIC-NEXT: xorl %ecx, %ecx
; GENERIC-NEXT: testb $1, %al
; GENERIC-NEXT: movl $-3840, %eax ## imm = 0xF100
; GENERIC-NEXT: cmovnel %ecx, %eax
; GENERIC-NEXT: cmpl $32768, %eax ## imm = 0x8000
; GENERIC-NEXT: jge LBB1_1
; GENERIC-NEXT: ## %bb.2: ## %bb91
; GENERIC-NEXT: xorl %eax, %eax
; GENERIC-NEXT: popq %rcx
; GENERIC-NEXT: retq
; GENERIC-NEXT: LBB1_1: ## %bb90
; GENERIC-NEXT: ud2
;
; ATOM-LABEL: test2:
; ATOM: ## %bb.0: ## %entry
; ATOM-NEXT: pushq %rax
; ATOM-NEXT: callq _return_false
; ATOM-NEXT: xorl %ecx, %ecx
; ATOM-NEXT: movl $-3840, %edx ## imm = 0xF100
; ATOM-NEXT: testb $1, %al
; ATOM-NEXT: cmovnel %ecx, %edx
; ATOM-NEXT: cmpl $32768, %edx ## imm = 0x8000
; ATOM-NEXT: jge LBB1_1
; ATOM-NEXT: ## %bb.2: ## %bb91
; ATOM-NEXT: xorl %eax, %eax
; ATOM-NEXT: popq %rcx
; ATOM-NEXT: retq
; ATOM-NEXT: LBB1_1: ## %bb90
; ATOM-NEXT: ud2
;
; ATHLON-LABEL: test2:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: subl $12, %esp
; ATHLON-NEXT: calll _return_false
; ATHLON-NEXT: xorl %ecx, %ecx
; ATHLON-NEXT: testb $1, %al
; ATHLON-NEXT: movl $-3840, %eax ## imm = 0xF100
; ATHLON-NEXT: cmovnel %ecx, %eax
; ATHLON-NEXT: cmpl $32768, %eax ## imm = 0x8000
; ATHLON-NEXT: jge LBB1_1
; ATHLON-NEXT: ## %bb.2: ## %bb91
; ATHLON-NEXT: xorl %eax, %eax
; ATHLON-NEXT: addl $12, %esp
; ATHLON-NEXT: retl
; ATHLON-NEXT: LBB1_1: ## %bb90
; ATHLON-NEXT: ud2
;
; MCU-LABEL: test2:
; MCU: # %bb.0: # %entry
; MCU-NEXT: calll return_false@PLT
; MCU-NEXT: xorl %ecx, %ecx
; MCU-NEXT: testb $1, %al
; MCU-NEXT: jne .LBB1_2
; MCU-NEXT: # %bb.1: # %entry
; MCU-NEXT: movl $-3840, %ecx # imm = 0xF100
; MCU-NEXT: .LBB1_2: # %entry
; MCU-NEXT: cmpl $32768, %ecx # imm = 0x8000
; MCU-NEXT: jge .LBB1_3
; MCU-NEXT: # %bb.4: # %bb91
; MCU-NEXT: xorl %eax, %eax
; MCU-NEXT: retl
; MCU-NEXT: .LBB1_3: # %bb90
entry:
%tmp73 = tail call i1 @return_false()
%g.0 = select i1 %tmp73, i16 0, i16 -480
%tmp7778 = sext i16 %g.0 to i32
%tmp80 = shl i32 %tmp7778, 3
%tmp87 = icmp sgt i32 %tmp80, 32767
br i1 %tmp87, label %bb90, label %bb91
bb90:
unreachable
bb91:
ret i32 0
}
declare i1 @return_false()
;; Select between two floating point constants.
define float @test3(i32 %x) nounwind readnone {
; GENERIC-LABEL: test3:
; GENERIC: ## %bb.0: ## %entry
; GENERIC-NEXT: xorl %eax, %eax
; GENERIC-NEXT: testl %edi, %edi
; GENERIC-NEXT: sete %al
; GENERIC-NEXT: leaq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %rcx
; GENERIC-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test3:
; ATOM: ## %bb.0: ## %entry
; ATOM-NEXT: xorl %eax, %eax
; ATOM-NEXT: leaq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %rcx
; ATOM-NEXT: testl %edi, %edi
; ATOM-NEXT: sete %al
; ATOM-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test3:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: xorl %eax, %eax
; ATHLON-NEXT: cmpl $0, {{[0-9]+}}(%esp)
; ATHLON-NEXT: sete %al
; ATHLON-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
; ATHLON-NEXT: retl
;
; MCU-LABEL: test3:
; MCU: # %bb.0: # %entry
; MCU-NEXT: xorl %ecx, %ecx
; MCU-NEXT: testl %eax, %eax
; MCU-NEXT: sete %cl
; MCU-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}(,%ecx,4)
; MCU-NEXT: retl
entry:
%0 = icmp eq i32 %x, 0
%iftmp.0.0 = select i1 %0, float 4.200000e+01, float 2.300000e+01
ret float %iftmp.0.0
}
define signext i8 @test4(i8* nocapture %P, double %F) nounwind readonly {
; CHECK-LABEL: test4:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: ucomisd %xmm0, %xmm1
; CHECK-NEXT: seta %al
; CHECK-NEXT: movsbl (%rdi,%rax,4), %eax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: test4:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: fldl {{[0-9]+}}(%esp)
; ATHLON-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
; ATHLON-NEXT: xorl %ecx, %ecx
; ATHLON-NEXT: fucompi %st(1), %st
; ATHLON-NEXT: fstp %st(0)
; ATHLON-NEXT: seta %cl
; ATHLON-NEXT: movsbl (%eax,%ecx,4), %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: test4:
; MCU: # %bb.0: # %entry
; MCU-NEXT: movl %eax, %ecx
; MCU-NEXT: fldl {{[0-9]+}}(%esp)
; MCU-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
; MCU-NEXT: fucompp
; MCU-NEXT: fnstsw %ax
; MCU-NEXT: xorl %edx, %edx
; MCU-NEXT: # kill: def $ah killed $ah killed $ax
; MCU-NEXT: sahf
; MCU-NEXT: seta %dl
; MCU-NEXT: movb (%ecx,%edx,4), %al
; MCU-NEXT: retl
entry:
%0 = fcmp olt double %F, 4.200000e+01
%iftmp.0.0 = select i1 %0, i32 4, i32 0
%1 = getelementptr i8, i8* %P, i32 %iftmp.0.0
%2 = load i8, i8* %1, align 1
ret i8 %2
}
define void @test5(i1 %c, <2 x i16> %a, <2 x i16> %b, <2 x i16>* %p) nounwind {
; GENERIC-LABEL: test5:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: testb $1, %dil
; GENERIC-NEXT: jne LBB4_2
; GENERIC-NEXT: ## %bb.1:
; GENERIC-NEXT: movaps %xmm1, %xmm0
; GENERIC-NEXT: LBB4_2:
; GENERIC-NEXT: movss %xmm0, (%rsi)
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test5:
; ATOM: ## %bb.0:
; ATOM-NEXT: testb $1, %dil
; ATOM-NEXT: jne LBB4_2
; ATOM-NEXT: ## %bb.1:
; ATOM-NEXT: movaps %xmm1, %xmm0
; ATOM-NEXT: LBB4_2:
; ATOM-NEXT: movss %xmm0, (%rsi)
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test5:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: pushl %esi
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: cmovnel %ecx, %edx
; ATHLON-NEXT: movzwl (%edx), %ecx
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %esi
; ATHLON-NEXT: cmovnel %edx, %esi
; ATHLON-NEXT: movzwl (%esi), %edx
; ATHLON-NEXT: movw %dx, 2(%eax)
; ATHLON-NEXT: movw %cx, (%eax)
; ATHLON-NEXT: popl %esi
; ATHLON-NEXT: retl
;
; MCU-LABEL: test5:
; MCU: # %bb.0:
; MCU-NEXT: pushl %esi
; MCU-NEXT: movl {{[0-9]+}}(%esp), %esi
; MCU-NEXT: testb $1, %al
; MCU-NEXT: jne .LBB4_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
; MCU-NEXT: movzwl {{[0-9]+}}(%esp), %edx
; MCU-NEXT: .LBB4_2:
; MCU-NEXT: movw %cx, 2(%esi)
; MCU-NEXT: movw %dx, (%esi)
; MCU-NEXT: popl %esi
; MCU-NEXT: retl
%x = select i1 %c, <2 x i16> %a, <2 x i16> %b
store <2 x i16> %x, <2 x i16>* %p
ret void
}
; Verify that the fmul gets sunk into the one part of the diamond where it is needed.
define void @test6(i32 %C, <4 x float>* %A, <4 x float>* %B) nounwind {
; CHECK-LABEL: test6:
; CHECK: ## %bb.0:
; CHECK-NEXT: testl %edi, %edi
; CHECK-NEXT: je LBB5_1
; CHECK-NEXT: ## %bb.2:
; CHECK-NEXT: movaps (%rsi), %xmm0
; CHECK-NEXT: movaps %xmm0, (%rsi)
; CHECK-NEXT: retq
; CHECK-NEXT: LBB5_1:
; CHECK-NEXT: movaps (%rdx), %xmm0
; CHECK-NEXT: mulps %xmm0, %xmm0
; CHECK-NEXT: movaps %xmm0, (%rsi)
; CHECK-NEXT: retq
;
; ATHLON-LABEL: test6:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: flds 12(%eax)
; ATHLON-NEXT: flds 8(%eax)
; ATHLON-NEXT: flds 4(%eax)
; ATHLON-NEXT: flds (%eax)
; ATHLON-NEXT: flds (%ecx)
; ATHLON-NEXT: fmul %st, %st(0)
; ATHLON-NEXT: cmpl $0, {{[0-9]+}}(%esp)
; ATHLON-NEXT: fxch %st(1)
; ATHLON-NEXT: fcmove %st(1), %st
; ATHLON-NEXT: fstp %st(1)
; ATHLON-NEXT: flds 4(%ecx)
; ATHLON-NEXT: fmul %st, %st(0)
; ATHLON-NEXT: fxch %st(2)
; ATHLON-NEXT: fcmove %st(2), %st
; ATHLON-NEXT: fstp %st(2)
; ATHLON-NEXT: flds 8(%ecx)
; ATHLON-NEXT: fmul %st, %st(0)
; ATHLON-NEXT: fxch %st(3)
; ATHLON-NEXT: fcmove %st(3), %st
; ATHLON-NEXT: fstp %st(3)
; ATHLON-NEXT: flds 12(%ecx)
; ATHLON-NEXT: fmul %st, %st(0)
; ATHLON-NEXT: fxch %st(4)
; ATHLON-NEXT: fcmove %st(4), %st
; ATHLON-NEXT: fstp %st(4)
; ATHLON-NEXT: fxch %st(3)
; ATHLON-NEXT: fstps 12(%eax)
; ATHLON-NEXT: fxch %st(1)
; ATHLON-NEXT: fstps 8(%eax)
; ATHLON-NEXT: fstps 4(%eax)
; ATHLON-NEXT: fstps (%eax)
; ATHLON-NEXT: retl
;
; MCU-LABEL: test6:
; MCU: # %bb.0:
; MCU-NEXT: pushl %eax
; MCU-NEXT: flds 12(%edx)
; MCU-NEXT: fstps (%esp) # 4-byte Folded Spill
; MCU-NEXT: flds 8(%edx)
; MCU-NEXT: flds 4(%edx)
; MCU-NEXT: flds (%ecx)
; MCU-NEXT: flds 4(%ecx)
; MCU-NEXT: flds 8(%ecx)
; MCU-NEXT: flds 12(%ecx)
; MCU-NEXT: fmul %st, %st(0)
; MCU-NEXT: fxch %st(1)
; MCU-NEXT: fmul %st, %st(0)
; MCU-NEXT: fxch %st(2)
; MCU-NEXT: fmul %st, %st(0)
; MCU-NEXT: fxch %st(3)
; MCU-NEXT: fmul %st, %st(0)
; MCU-NEXT: testl %eax, %eax
; MCU-NEXT: flds (%edx)
; MCU-NEXT: je .LBB5_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: fstp %st(1)
; MCU-NEXT: fstp %st(3)
; MCU-NEXT: fstp %st(1)
; MCU-NEXT: fstp %st(0)
; MCU-NEXT: flds (%esp) # 4-byte Folded Reload
; MCU-NEXT: fldz
; MCU-NEXT: fldz
; MCU-NEXT: fldz
; MCU-NEXT: fxch %st(1)
; MCU-NEXT: fxch %st(6)
; MCU-NEXT: fxch %st(1)
; MCU-NEXT: fxch %st(5)
; MCU-NEXT: fxch %st(4)
; MCU-NEXT: fxch %st(1)
; MCU-NEXT: fxch %st(3)
; MCU-NEXT: fxch %st(2)
; MCU-NEXT: .LBB5_2:
; MCU-NEXT: fstp %st(0)
; MCU-NEXT: fstp %st(5)
; MCU-NEXT: fstp %st(3)
; MCU-NEXT: fxch %st(2)
; MCU-NEXT: fstps 12(%edx)
; MCU-NEXT: fxch %st(1)
; MCU-NEXT: fstps 8(%edx)
; MCU-NEXT: fstps 4(%edx)
; MCU-NEXT: fstps (%edx)
; MCU-NEXT: popl %eax
; MCU-NEXT: retl
%tmp = load <4 x float>, <4 x float>* %A
%tmp3 = load <4 x float>, <4 x float>* %B
%tmp9 = fmul <4 x float> %tmp3, %tmp3
%tmp.upgrd.1 = icmp eq i32 %C, 0
%iftmp.38.0 = select i1 %tmp.upgrd.1, <4 x float> %tmp9, <4 x float> %tmp
store <4 x float> %iftmp.38.0, <4 x float>* %A
ret void
}
; Select with fp80's
define x86_fp80 @test7(i32 %tmp8) nounwind {
; GENERIC-LABEL: test7:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: xorl %eax, %eax
; GENERIC-NEXT: testl %edi, %edi
; GENERIC-NEXT: setns %al
; GENERIC-NEXT: shlq $4, %rax
; GENERIC-NEXT: leaq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %rcx
; GENERIC-NEXT: fldt (%rax,%rcx)
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test7:
; ATOM: ## %bb.0:
; ATOM-NEXT: xorl %eax, %eax
; ATOM-NEXT: leaq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %rcx
; ATOM-NEXT: testl %edi, %edi
; ATOM-NEXT: setns %al
; ATOM-NEXT: shlq $4, %rax
; ATOM-NEXT: fldt (%rax,%rcx)
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test7:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: notl %eax
; ATHLON-NEXT: shrl $27, %eax
; ATHLON-NEXT: andl $-16, %eax
; ATHLON-NEXT: fldt {{\.?LCPI[0-9]+_[0-9]+}}(%eax)
; ATHLON-NEXT: retl
;
; MCU-LABEL: test7:
; MCU: # %bb.0:
; MCU-NEXT: notl %eax
; MCU-NEXT: shrl $27, %eax
; MCU-NEXT: andl $-16, %eax
; MCU-NEXT: fldt {{\.?LCPI[0-9]+_[0-9]+}}(%eax)
; MCU-NEXT: retl
%tmp9 = icmp sgt i32 %tmp8, -1
%retval = select i1 %tmp9, x86_fp80 0xK4005B400000000000000, x86_fp80 0xK40078700000000000000
ret x86_fp80 %retval
}
; widening select v6i32 and then a sub
define void @test8(i1 %c, <6 x i32>* %dst.addr, <6 x i32> %src1,<6 x i32> %src2) nounwind {
; GENERIC-LABEL: test8:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: testb $1, %dil
; GENERIC-NEXT: jne LBB7_1
; GENERIC-NEXT: ## %bb.2:
; GENERIC-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
; GENERIC-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
; GENERIC-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
; GENERIC-NEXT: movd {{.*#+}} xmm2 = mem[0],zero,zero,zero
; GENERIC-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
; GENERIC-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
; GENERIC-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
; GENERIC-NEXT: movd {{.*#+}} xmm2 = mem[0],zero,zero,zero
; GENERIC-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
; GENERIC-NEXT: jmp LBB7_3
; GENERIC-NEXT: LBB7_1:
; GENERIC-NEXT: movd %r9d, %xmm0
; GENERIC-NEXT: movd %r8d, %xmm1
; GENERIC-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
; GENERIC-NEXT: movd %ecx, %xmm2
; GENERIC-NEXT: movd %edx, %xmm0
; GENERIC-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
; GENERIC-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
; GENERIC-NEXT: movd {{.*#+}} xmm2 = mem[0],zero,zero,zero
; GENERIC-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
; GENERIC-NEXT: LBB7_3:
; GENERIC-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
; GENERIC-NEXT: pcmpeqd %xmm2, %xmm2
; GENERIC-NEXT: paddd %xmm2, %xmm0
; GENERIC-NEXT: paddd %xmm2, %xmm1
; GENERIC-NEXT: movq %xmm1, 16(%rsi)
; GENERIC-NEXT: movdqa %xmm0, (%rsi)
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test8:
; ATOM: ## %bb.0:
; ATOM-NEXT: testb $1, %dil
; ATOM-NEXT: jne LBB7_1
; ATOM-NEXT: ## %bb.2:
; ATOM-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
; ATOM-NEXT: movd {{.*#+}} xmm2 = mem[0],zero,zero,zero
; ATOM-NEXT: movd {{.*#+}} xmm3 = mem[0],zero,zero,zero
; ATOM-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
; ATOM-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
; ATOM-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
; ATOM-NEXT: movd {{.*#+}} xmm3 = mem[0],zero,zero,zero
; ATOM-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
; ATOM-NEXT: jmp LBB7_3
; ATOM-NEXT: LBB7_1:
; ATOM-NEXT: movd %r9d, %xmm1
; ATOM-NEXT: movd %r8d, %xmm2
; ATOM-NEXT: movd %ecx, %xmm3
; ATOM-NEXT: movd %edx, %xmm0
; ATOM-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
; ATOM-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
; ATOM-NEXT: movd {{.*#+}} xmm3 = mem[0],zero,zero,zero
; ATOM-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
; ATOM-NEXT: LBB7_3:
; ATOM-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
; ATOM-NEXT: pcmpeqd %xmm2, %xmm2
; ATOM-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
; ATOM-NEXT: paddd %xmm2, %xmm0
; ATOM-NEXT: paddd %xmm2, %xmm1
; ATOM-NEXT: movq %xmm1, 16(%rsi)
; ATOM-NEXT: movdqa %xmm0, (%rsi)
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test8:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: pushl %ebp
; ATHLON-NEXT: pushl %ebx
; ATHLON-NEXT: pushl %edi
; ATHLON-NEXT: pushl %esi
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: cmovnel %ecx, %eax
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: cmovnel %edx, %ecx
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %esi
; ATHLON-NEXT: cmovnel %edx, %esi
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %edi
; ATHLON-NEXT: cmovnel %edx, %edi
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %ebx
; ATHLON-NEXT: cmovnel %edx, %ebx
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %ebp
; ATHLON-NEXT: cmovnel %edx, %ebp
; ATHLON-NEXT: movl (%eax), %eax
; ATHLON-NEXT: movl (%ecx), %ecx
; ATHLON-NEXT: movl (%esi), %edx
; ATHLON-NEXT: movl (%edi), %esi
; ATHLON-NEXT: movl (%ebx), %ebx
; ATHLON-NEXT: movl (%ebp), %edi
; ATHLON-NEXT: decl %eax
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ebp
; ATHLON-NEXT: movl %eax, 20(%ebp)
; ATHLON-NEXT: decl %ecx
; ATHLON-NEXT: movl %ecx, 16(%ebp)
; ATHLON-NEXT: decl %edx
; ATHLON-NEXT: movl %edx, 12(%ebp)
; ATHLON-NEXT: decl %esi
; ATHLON-NEXT: movl %esi, 8(%ebp)
; ATHLON-NEXT: decl %ebx
; ATHLON-NEXT: movl %ebx, 4(%ebp)
; ATHLON-NEXT: decl %edi
; ATHLON-NEXT: movl %edi, (%ebp)
; ATHLON-NEXT: popl %esi
; ATHLON-NEXT: popl %edi
; ATHLON-NEXT: popl %ebx
; ATHLON-NEXT: popl %ebp
; ATHLON-NEXT: retl
;
; MCU-LABEL: test8:
; MCU: # %bb.0:
; MCU-NEXT: pushl %ebp
; MCU-NEXT: pushl %ebx
; MCU-NEXT: pushl %edi
; MCU-NEXT: pushl %esi
; MCU-NEXT: testb $1, %al
; MCU-NEXT: jne .LBB7_1
; MCU-NEXT: # %bb.2:
; MCU-NEXT: leal {{[0-9]+}}(%esp), %edi
; MCU-NEXT: je .LBB7_5
; MCU-NEXT: .LBB7_4:
; MCU-NEXT: leal {{[0-9]+}}(%esp), %ecx
; MCU-NEXT: je .LBB7_8
; MCU-NEXT: .LBB7_7:
; MCU-NEXT: leal {{[0-9]+}}(%esp), %esi
; MCU-NEXT: je .LBB7_11
; MCU-NEXT: .LBB7_10:
; MCU-NEXT: leal {{[0-9]+}}(%esp), %ebp
; MCU-NEXT: je .LBB7_14
; MCU-NEXT: .LBB7_13:
; MCU-NEXT: leal {{[0-9]+}}(%esp), %eax
; MCU-NEXT: jmp .LBB7_15
; MCU-NEXT: .LBB7_1:
; MCU-NEXT: leal {{[0-9]+}}(%esp), %edi
; MCU-NEXT: jne .LBB7_4
; MCU-NEXT: .LBB7_5:
; MCU-NEXT: leal {{[0-9]+}}(%esp), %ecx
; MCU-NEXT: jne .LBB7_7
; MCU-NEXT: .LBB7_8:
; MCU-NEXT: leal {{[0-9]+}}(%esp), %esi
; MCU-NEXT: jne .LBB7_10
; MCU-NEXT: .LBB7_11:
; MCU-NEXT: leal {{[0-9]+}}(%esp), %ebp
; MCU-NEXT: jne .LBB7_13
; MCU-NEXT: .LBB7_14:
; MCU-NEXT: leal {{[0-9]+}}(%esp), %eax
; MCU-NEXT: .LBB7_15:
; MCU-NEXT: movl (%edi), %ebx
; MCU-NEXT: movl (%ecx), %edi
; MCU-NEXT: movl (%esi), %esi
; MCU-NEXT: movl (%ebp), %ecx
; MCU-NEXT: movl (%eax), %eax
; MCU-NEXT: jne .LBB7_16
; MCU-NEXT: # %bb.17:
; MCU-NEXT: leal {{[0-9]+}}(%esp), %ebp
; MCU-NEXT: jmp .LBB7_18
; MCU-NEXT: .LBB7_16:
; MCU-NEXT: leal {{[0-9]+}}(%esp), %ebp
; MCU-NEXT: .LBB7_18:
; MCU-NEXT: movl (%ebp), %ebp
; MCU-NEXT: decl %ebp
; MCU-NEXT: decl %eax
; MCU-NEXT: decl %ecx
; MCU-NEXT: decl %esi
; MCU-NEXT: decl %edi
; MCU-NEXT: decl %ebx
; MCU-NEXT: movl %ebx, 20(%edx)
; MCU-NEXT: movl %edi, 16(%edx)
; MCU-NEXT: movl %esi, 12(%edx)
; MCU-NEXT: movl %ecx, 8(%edx)
; MCU-NEXT: movl %eax, 4(%edx)
; MCU-NEXT: movl %ebp, (%edx)
; MCU-NEXT: popl %esi
; MCU-NEXT: popl %edi
; MCU-NEXT: popl %ebx
; MCU-NEXT: popl %ebp
; MCU-NEXT: retl
%x = select i1 %c, <6 x i32> %src1, <6 x i32> %src2
%val = sub <6 x i32> %x, < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 >
store <6 x i32> %val, <6 x i32>* %dst.addr
ret void
}
;; Test integer select between values and constants.
define i64 @test9(i64 %x, i64 %y) nounwind readnone ssp noredzone {
; CHECK-LABEL: test9:
; CHECK: ## %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $1, %rdi
; CHECK-NEXT: sbbq %rax, %rax
; CHECK-NEXT: orq %rsi, %rax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: test9:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: orl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movl $-1, %eax
; ATHLON-NEXT: movl $-1, %edx
; ATHLON-NEXT: je LBB8_2
; ATHLON-NEXT: ## %bb.1:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: LBB8_2:
; ATHLON-NEXT: retl
;
; MCU-LABEL: test9:
; MCU: # %bb.0:
; MCU-NEXT: orl %edx, %eax
; MCU-NEXT: jne .LBB8_1
; MCU-NEXT: # %bb.2:
; MCU-NEXT: movl $-1, %eax
; MCU-NEXT: movl $-1, %edx
; MCU-NEXT: retl
; MCU-NEXT: .LBB8_1:
; MCU-NEXT: movl {{[0-9]+}}(%esp), %eax
; MCU-NEXT: movl {{[0-9]+}}(%esp), %edx
; MCU-NEXT: retl
%cmp = icmp ne i64 %x, 0
%cond = select i1 %cmp, i64 %y, i64 -1
ret i64 %cond
}
;; Same as test9
define i64 @test9a(i64 %x, i64 %y) nounwind readnone ssp noredzone {
; CHECK-LABEL: test9a:
; CHECK: ## %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $1, %rdi
; CHECK-NEXT: sbbq %rax, %rax
; CHECK-NEXT: orq %rsi, %rax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: test9a:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: orl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movl $-1, %eax
; ATHLON-NEXT: movl $-1, %edx
; ATHLON-NEXT: je LBB9_2
; ATHLON-NEXT: ## %bb.1:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: LBB9_2:
; ATHLON-NEXT: retl
;
; MCU-LABEL: test9a:
; MCU: # %bb.0:
; MCU-NEXT: orl %edx, %eax
; MCU-NEXT: movl $-1, %eax
; MCU-NEXT: movl $-1, %edx
; MCU-NEXT: je .LBB9_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: movl {{[0-9]+}}(%esp), %eax
; MCU-NEXT: movl {{[0-9]+}}(%esp), %edx
; MCU-NEXT: .LBB9_2:
; MCU-NEXT: retl
%cmp = icmp eq i64 %x, 0
%cond = select i1 %cmp, i64 -1, i64 %y
ret i64 %cond
}
define i64 @test9b(i64 %x, i64 %y) nounwind readnone ssp noredzone {
; GENERIC-LABEL: test9b:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: cmpq $1, %rdi
; GENERIC-NEXT: sbbq %rax, %rax
; GENERIC-NEXT: orq %rsi, %rax
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test9b:
; ATOM: ## %bb.0:
; ATOM-NEXT: cmpq $1, %rdi
; ATOM-NEXT: sbbq %rax, %rax
; ATOM-NEXT: orq %rsi, %rax
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test9b:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: xorl %edx, %edx
; ATHLON-NEXT: orl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: sete %dl
; ATHLON-NEXT: negl %edx
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: orl %edx, %eax
; ATHLON-NEXT: orl {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: retl
;
; MCU-LABEL: test9b:
; MCU: # %bb.0:
; MCU-NEXT: movl %edx, %ecx
; MCU-NEXT: xorl %edx, %edx
; MCU-NEXT: orl %ecx, %eax
; MCU-NEXT: sete %dl
; MCU-NEXT: negl %edx
; MCU-NEXT: movl {{[0-9]+}}(%esp), %eax
; MCU-NEXT: orl %edx, %eax
; MCU-NEXT: orl {{[0-9]+}}(%esp), %edx
; MCU-NEXT: retl
%cmp = icmp eq i64 %x, 0
%A = sext i1 %cmp to i64
%cond = or i64 %y, %A
ret i64 %cond
}
;; Select between -1 and 1.
define i64 @test10(i64 %x, i64 %y) nounwind readnone ssp noredzone {
; CHECK-LABEL: test10:
; CHECK: ## %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: testq %rdi, %rdi
; CHECK-NEXT: setne %al
; CHECK-NEXT: leaq -1(%rax,%rax), %rax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: test10:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: xorl %edx, %edx
; ATHLON-NEXT: orl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movl $-1, %ecx
; ATHLON-NEXT: movl $1, %eax
; ATHLON-NEXT: cmovel %ecx, %eax
; ATHLON-NEXT: cmovel %ecx, %edx
; ATHLON-NEXT: retl
;
; MCU-LABEL: test10:
; MCU: # %bb.0:
; MCU-NEXT: orl %edx, %eax
; MCU-NEXT: movl $-1, %eax
; MCU-NEXT: movl $-1, %edx
; MCU-NEXT: je .LBB11_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: xorl %edx, %edx
; MCU-NEXT: movl $1, %eax
; MCU-NEXT: .LBB11_2:
; MCU-NEXT: retl
%cmp = icmp eq i64 %x, 0
%cond = select i1 %cmp, i64 -1, i64 1
ret i64 %cond
}
define i64 @test11(i64 %x, i64 %y) nounwind readnone ssp noredzone {
; CHECK-LABEL: test11:
; CHECK: ## %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $1, %rdi
; CHECK-NEXT: sbbq %rax, %rax
; CHECK-NEXT: notq %rax
; CHECK-NEXT: orq %rsi, %rax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: test11:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: orl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movl $-1, %eax
; ATHLON-NEXT: movl $-1, %edx
; ATHLON-NEXT: jne LBB12_2
; ATHLON-NEXT: ## %bb.1:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: LBB12_2:
; ATHLON-NEXT: retl
;
; MCU-LABEL: test11:
; MCU: # %bb.0:
; MCU-NEXT: orl %edx, %eax
; MCU-NEXT: je .LBB12_1
; MCU-NEXT: # %bb.2:
; MCU-NEXT: movl $-1, %eax
; MCU-NEXT: movl $-1, %edx
; MCU-NEXT: retl
; MCU-NEXT: .LBB12_1:
; MCU-NEXT: movl {{[0-9]+}}(%esp), %eax
; MCU-NEXT: movl {{[0-9]+}}(%esp), %edx
; MCU-NEXT: retl
%cmp = icmp eq i64 %x, 0
%cond = select i1 %cmp, i64 %y, i64 -1
ret i64 %cond
}
define i64 @test11a(i64 %x, i64 %y) nounwind readnone ssp noredzone {
; CHECK-LABEL: test11a:
; CHECK: ## %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $1, %rdi
; CHECK-NEXT: sbbq %rax, %rax
; CHECK-NEXT: notq %rax
; CHECK-NEXT: orq %rsi, %rax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: test11a:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: orl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movl $-1, %eax
; ATHLON-NEXT: movl $-1, %edx
; ATHLON-NEXT: jne LBB13_2
; ATHLON-NEXT: ## %bb.1:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: LBB13_2:
; ATHLON-NEXT: retl
;
; MCU-LABEL: test11a:
; MCU: # %bb.0:
; MCU-NEXT: orl %edx, %eax
; MCU-NEXT: movl $-1, %eax
; MCU-NEXT: movl $-1, %edx
; MCU-NEXT: jne .LBB13_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: movl {{[0-9]+}}(%esp), %eax
; MCU-NEXT: movl {{[0-9]+}}(%esp), %edx
; MCU-NEXT: .LBB13_2:
; MCU-NEXT: retl
%cmp = icmp ne i64 %x, 0
%cond = select i1 %cmp, i64 -1, i64 %y
ret i64 %cond
}
define i32 @test13(i32 %a, i32 %b) nounwind {
; GENERIC-LABEL: test13:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: cmpl %esi, %edi
; GENERIC-NEXT: sbbl %eax, %eax
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test13:
; ATOM: ## %bb.0:
; ATOM-NEXT: cmpl %esi, %edi
; ATOM-NEXT: sbbl %eax, %eax
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test13:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: cmpl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: sbbl %eax, %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: test13:
; MCU: # %bb.0:
; MCU-NEXT: cmpl %edx, %eax
; MCU-NEXT: sbbl %eax, %eax
; MCU-NEXT: retl
%c = icmp ult i32 %a, %b
%d = sext i1 %c to i32
ret i32 %d
}
define i32 @test14(i32 %a, i32 %b) nounwind {
; GENERIC-LABEL: test14:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: xorl %eax, %eax
; GENERIC-NEXT: cmpl %esi, %edi
; GENERIC-NEXT: adcl $-1, %eax
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test14:
; ATOM: ## %bb.0:
; ATOM-NEXT: xorl %eax, %eax
; ATOM-NEXT: cmpl %esi, %edi
; ATOM-NEXT: adcl $-1, %eax
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test14:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: xorl %eax, %eax
; ATHLON-NEXT: cmpl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: adcl $-1, %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: test14:
; MCU: # %bb.0:
; MCU-NEXT: xorl %ecx, %ecx
; MCU-NEXT: cmpl %edx, %eax
; MCU-NEXT: adcl $-1, %ecx
; MCU-NEXT: movl %ecx, %eax
; MCU-NEXT: retl
%c = icmp uge i32 %a, %b
%d = sext i1 %c to i32
ret i32 %d
}
; rdar://10961709
define i32 @test15(i32 %x) nounwind {
; GENERIC-LABEL: test15:
; GENERIC: ## %bb.0: ## %entry
; GENERIC-NEXT: negl %edi
; GENERIC-NEXT: sbbl %eax, %eax
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test15:
; ATOM: ## %bb.0: ## %entry
; ATOM-NEXT: negl %edi
; ATOM-NEXT: sbbl %eax, %eax
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test15:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: xorl %eax, %eax
; ATHLON-NEXT: cmpl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: sbbl %eax, %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: test15:
; MCU: # %bb.0: # %entry
; MCU-NEXT: negl %eax
; MCU-NEXT: sbbl %eax, %eax
; MCU-NEXT: retl
entry:
%cmp = icmp ne i32 %x, 0
%sub = sext i1 %cmp to i32
ret i32 %sub
}
define i64 @test16(i64 %x) nounwind uwtable readnone ssp {
; GENERIC-LABEL: test16:
; GENERIC: ## %bb.0: ## %entry
; GENERIC-NEXT: negq %rdi
; GENERIC-NEXT: sbbq %rax, %rax
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test16:
; ATOM: ## %bb.0: ## %entry
; ATOM-NEXT: negq %rdi
; ATOM-NEXT: sbbq %rax, %rax
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test16:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: xorl %eax, %eax
; ATHLON-NEXT: orl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: setne %al
; ATHLON-NEXT: negl %eax
; ATHLON-NEXT: movl %eax, %edx
; ATHLON-NEXT: retl
;
; MCU-LABEL: test16:
; MCU: # %bb.0: # %entry
; MCU-NEXT: movl %eax, %ecx
; MCU-NEXT: xorl %eax, %eax
; MCU-NEXT: orl %edx, %ecx
; MCU-NEXT: setne %al
; MCU-NEXT: negl %eax
; MCU-NEXT: movl %eax, %edx
; MCU-NEXT: retl
entry:
%cmp = icmp ne i64 %x, 0
%conv1 = sext i1 %cmp to i64
ret i64 %conv1
}
define i16 @test17(i16 %x) nounwind {
; GENERIC-LABEL: test17:
; GENERIC: ## %bb.0: ## %entry
; GENERIC-NEXT: negw %di
; GENERIC-NEXT: sbbl %eax, %eax
; GENERIC-NEXT: ## kill: def $ax killed $ax killed $eax
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test17:
; ATOM: ## %bb.0: ## %entry
; ATOM-NEXT: negw %di
; ATOM-NEXT: sbbl %eax, %eax
; ATOM-NEXT: ## kill: def $ax killed $ax killed $eax
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test17:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: xorl %eax, %eax
; ATHLON-NEXT: cmpw {{[0-9]+}}(%esp), %ax
; ATHLON-NEXT: sbbl %eax, %eax
; ATHLON-NEXT: ## kill: def $ax killed $ax killed $eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: test17:
; MCU: # %bb.0: # %entry
; MCU-NEXT: negw %ax
; MCU-NEXT: sbbl %eax, %eax
; MCU-NEXT: # kill: def $ax killed $ax killed $eax
; MCU-NEXT: retl
entry:
%cmp = icmp ne i16 %x, 0
%sub = sext i1 %cmp to i16
ret i16 %sub
}
define i8 @test18(i32 %x, i8 zeroext %a, i8 zeroext %b) nounwind {
; GENERIC-LABEL: test18:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: movl %esi, %eax
; GENERIC-NEXT: cmpl $15, %edi
; GENERIC-NEXT: cmovgel %edx, %eax
; GENERIC-NEXT: ## kill: def $al killed $al killed $eax
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test18:
; ATOM: ## %bb.0:
; ATOM-NEXT: movl %esi, %eax
; ATOM-NEXT: cmpl $15, %edi
; ATOM-NEXT: cmovgel %edx, %eax
; ATOM-NEXT: ## kill: def $al killed $al killed $eax
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test18:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: cmpl $15, {{[0-9]+}}(%esp)
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: cmovll %eax, %ecx
; ATHLON-NEXT: movb (%ecx), %al
; ATHLON-NEXT: retl
;
; MCU-LABEL: test18:
; MCU: # %bb.0:
; MCU-NEXT: cmpl $15, %eax
; MCU-NEXT: jl .LBB19_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: movl %ecx, %edx
; MCU-NEXT: .LBB19_2:
; MCU-NEXT: movl %edx, %eax
; MCU-NEXT: retl
%cmp = icmp slt i32 %x, 15
%sel = select i1 %cmp, i8 %a, i8 %b
ret i8 %sel
}
define i32 @trunc_select_miscompile(i32 %a, i1 zeroext %cc) {
; GENERIC-LABEL: trunc_select_miscompile:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: ## kill: def $esi killed $esi def $rsi
; GENERIC-NEXT: movl %edi, %eax
; GENERIC-NEXT: leal 2(%rsi), %ecx
; GENERIC-NEXT: ## kill: def $cl killed $cl killed $ecx
; GENERIC-NEXT: shll %cl, %eax
; GENERIC-NEXT: retq
;
; ATOM-LABEL: trunc_select_miscompile:
; ATOM: ## %bb.0:
; ATOM-NEXT: ## kill: def $esi killed $esi def $rsi
; ATOM-NEXT: leal 2(%rsi), %ecx
; ATOM-NEXT: movl %edi, %eax
; ATOM-NEXT: ## kill: def $cl killed $cl killed $ecx
; ATOM-NEXT: shll %cl, %eax
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: trunc_select_miscompile:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movb {{[0-9]+}}(%esp), %cl
; ATHLON-NEXT: orb $2, %cl
; ATHLON-NEXT: shll %cl, %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: trunc_select_miscompile:
; MCU: # %bb.0:
; MCU-NEXT: movl %edx, %ecx
; MCU-NEXT: orb $2, %cl
; MCU-NEXT: # kill: def $cl killed $cl killed $ecx
; MCU-NEXT: shll %cl, %eax
; MCU-NEXT: retl
%tmp1 = select i1 %cc, i32 3, i32 2
%tmp2 = shl i32 %a, %tmp1
ret i32 %tmp2
}
; reproducer for pr29002
define void @clamp_i8(i32 %src, i8* %dst) {
; GENERIC-LABEL: clamp_i8:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: cmpl $127, %edi
; GENERIC-NEXT: movl $127, %eax
; GENERIC-NEXT: cmovlel %edi, %eax
; GENERIC-NEXT: cmpl $-128, %eax
; GENERIC-NEXT: movl $128, %ecx
; GENERIC-NEXT: cmovgel %eax, %ecx
; GENERIC-NEXT: movb %cl, (%rsi)
; GENERIC-NEXT: retq
;
; ATOM-LABEL: clamp_i8:
; ATOM: ## %bb.0:
; ATOM-NEXT: cmpl $127, %edi
; ATOM-NEXT: movl $127, %eax
; ATOM-NEXT: movl $128, %ecx
; ATOM-NEXT: cmovlel %edi, %eax
; ATOM-NEXT: cmpl $-128, %eax
; ATOM-NEXT: cmovgel %eax, %ecx
; ATOM-NEXT: movb %cl, (%rsi)
; ATOM-NEXT: retq
;
; ATHLON-LABEL: clamp_i8:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: cmpl $127, %ecx
; ATHLON-NEXT: movl $127, %edx
; ATHLON-NEXT: cmovlel %ecx, %edx
; ATHLON-NEXT: cmpl $-128, %edx
; ATHLON-NEXT: movl $128, %ecx
; ATHLON-NEXT: cmovgel %edx, %ecx
; ATHLON-NEXT: movb %cl, (%eax)
; ATHLON-NEXT: retl
;
; MCU-LABEL: clamp_i8:
; MCU: # %bb.0:
; MCU-NEXT: cmpl $127, %eax
; MCU-NEXT: movl $127, %ecx
; MCU-NEXT: jg .LBB21_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: movl %eax, %ecx
; MCU-NEXT: .LBB21_2:
; MCU-NEXT: cmpl $-128, %ecx
; MCU-NEXT: movb $-128, %al
; MCU-NEXT: jl .LBB21_4
; MCU-NEXT: # %bb.3:
; MCU-NEXT: movl %ecx, %eax
; MCU-NEXT: .LBB21_4:
; MCU-NEXT: movb %al, (%edx)
; MCU-NEXT: retl
%cmp = icmp sgt i32 %src, 127
%sel1 = select i1 %cmp, i32 127, i32 %src
%cmp1 = icmp slt i32 %sel1, -128
%sel2 = select i1 %cmp1, i32 -128, i32 %sel1
%conv = trunc i32 %sel2 to i8
store i8 %conv, i8* %dst, align 2
ret void
}
; reproducer for pr29002
define void @clamp(i32 %src, i16* %dst) {
; GENERIC-LABEL: clamp:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: cmpl $32768, %edi ## imm = 0x8000
; GENERIC-NEXT: movl $32767, %eax ## imm = 0x7FFF
; GENERIC-NEXT: cmovll %edi, %eax
; GENERIC-NEXT: cmpl $-32768, %eax ## imm = 0x8000
; GENERIC-NEXT: movl $32768, %ecx ## imm = 0x8000
; GENERIC-NEXT: cmovgel %eax, %ecx
; GENERIC-NEXT: movw %cx, (%rsi)
; GENERIC-NEXT: retq
;
; ATOM-LABEL: clamp:
; ATOM: ## %bb.0:
; ATOM-NEXT: cmpl $32768, %edi ## imm = 0x8000
; ATOM-NEXT: movl $32767, %eax ## imm = 0x7FFF
; ATOM-NEXT: movl $32768, %ecx ## imm = 0x8000
; ATOM-NEXT: cmovll %edi, %eax
; ATOM-NEXT: cmpl $-32768, %eax ## imm = 0x8000
; ATOM-NEXT: cmovgel %eax, %ecx
; ATOM-NEXT: movw %cx, (%rsi)
; ATOM-NEXT: retq
;
; ATHLON-LABEL: clamp:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: cmpl $32768, %ecx ## imm = 0x8000
; ATHLON-NEXT: movl $32767, %edx ## imm = 0x7FFF
; ATHLON-NEXT: cmovll %ecx, %edx
; ATHLON-NEXT: cmpl $-32768, %edx ## imm = 0x8000
; ATHLON-NEXT: movl $32768, %ecx ## imm = 0x8000
; ATHLON-NEXT: cmovgel %edx, %ecx
; ATHLON-NEXT: movw %cx, (%eax)
; ATHLON-NEXT: retl
;
; MCU-LABEL: clamp:
; MCU: # %bb.0:
; MCU-NEXT: cmpl $32768, %eax # imm = 0x8000
; MCU-NEXT: movl $32767, %ecx # imm = 0x7FFF
; MCU-NEXT: jge .LBB22_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: movl %eax, %ecx
; MCU-NEXT: .LBB22_2:
; MCU-NEXT: cmpl $-32768, %ecx # imm = 0x8000
; MCU-NEXT: movl $32768, %eax # imm = 0x8000
; MCU-NEXT: jl .LBB22_4
; MCU-NEXT: # %bb.3:
; MCU-NEXT: movl %ecx, %eax
; MCU-NEXT: .LBB22_4:
; MCU-NEXT: movw %ax, (%edx)
; MCU-NEXT: retl
%cmp = icmp sgt i32 %src, 32767
%sel1 = select i1 %cmp, i32 32767, i32 %src
%cmp1 = icmp slt i32 %sel1, -32768
%sel2 = select i1 %cmp1, i32 -32768, i32 %sel1
%conv = trunc i32 %sel2 to i16
store i16 %conv, i16* %dst, align 2
ret void
}
define i16 @select_xor_1(i16 %A, i8 %cond) {
; CHECK-LABEL: select_xor_1:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: xorl $43, %eax
; CHECK-NEXT: testb $1, %sil
; CHECK-NEXT: cmovel %edi, %eax
; CHECK-NEXT: ## kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: select_xor_1:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: movl %ecx, %eax
; ATHLON-NEXT: xorl $43, %eax
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: cmovel %ecx, %eax
; ATHLON-NEXT: ## kill: def $ax killed $ax killed $eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: select_xor_1:
; MCU: # %bb.0: # %entry
; MCU-NEXT: andl $1, %edx
; MCU-NEXT: negl %edx
; MCU-NEXT: andl $43, %edx
; MCU-NEXT: xorl %edx, %eax
; MCU-NEXT: # kill: def $ax killed $ax killed $eax
; MCU-NEXT: retl
entry:
%and = and i8 %cond, 1
%cmp10 = icmp eq i8 %and, 0
%0 = xor i16 %A, 43
%1 = select i1 %cmp10, i16 %A, i16 %0
ret i16 %1
}
; Equivalent to above, but with icmp ne (and %cond, 1), 1 instead of
; icmp eq (and %cond, 1), 0
define i16 @select_xor_1b(i16 %A, i8 %cond) {
; CHECK-LABEL: select_xor_1b:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: xorl $43, %eax
; CHECK-NEXT: testb $1, %sil
; CHECK-NEXT: cmovel %edi, %eax
; CHECK-NEXT: ## kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: select_xor_1b:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: movl %ecx, %eax
; ATHLON-NEXT: xorl $43, %eax
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: cmovel %ecx, %eax
; ATHLON-NEXT: ## kill: def $ax killed $ax killed $eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: select_xor_1b:
; MCU: # %bb.0: # %entry
; MCU-NEXT: testb $1, %dl
; MCU-NEXT: je .LBB24_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: xorl $43, %eax
; MCU-NEXT: .LBB24_2: # %entry
; MCU-NEXT: # kill: def $ax killed $ax killed $eax
; MCU-NEXT: retl
entry:
%and = and i8 %cond, 1
%cmp10 = icmp ne i8 %and, 1
%0 = xor i16 %A, 43
%1 = select i1 %cmp10, i16 %A, i16 %0
ret i16 %1
}
define i32 @select_xor_2(i32 %A, i32 %B, i8 %cond) {
; CHECK-LABEL: select_xor_2:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: xorl %edi, %eax
; CHECK-NEXT: testb $1, %dl
; CHECK-NEXT: cmovel %edi, %eax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: select_xor_2:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: xorl %ecx, %eax
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: cmovel %ecx, %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: select_xor_2:
; MCU: # %bb.0: # %entry
; MCU-NEXT: andl $1, %ecx
; MCU-NEXT: negl %ecx
; MCU-NEXT: andl %edx, %ecx
; MCU-NEXT: xorl %ecx, %eax
; MCU-NEXT: retl
entry:
%and = and i8 %cond, 1
%cmp10 = icmp eq i8 %and, 0
%0 = xor i32 %B, %A
%1 = select i1 %cmp10, i32 %A, i32 %0
ret i32 %1
}
; Equivalent to above, but with icmp ne (and %cond, 1), 1 instead of
; icmp eq (and %cond, 1), 0
define i32 @select_xor_2b(i32 %A, i32 %B, i8 %cond) {
; CHECK-LABEL: select_xor_2b:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: xorl %edi, %eax
; CHECK-NEXT: testb $1, %dl
; CHECK-NEXT: cmovel %edi, %eax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: select_xor_2b:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: xorl %ecx, %eax
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: cmovel %ecx, %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: select_xor_2b:
; MCU: # %bb.0: # %entry
; MCU-NEXT: testb $1, %cl
; MCU-NEXT: je .LBB26_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: xorl %edx, %eax
; MCU-NEXT: .LBB26_2: # %entry
; MCU-NEXT: retl
entry:
%and = and i8 %cond, 1
%cmp10 = icmp ne i8 %and, 1
%0 = xor i32 %B, %A
%1 = select i1 %cmp10, i32 %A, i32 %0
ret i32 %1
}
define i32 @select_or(i32 %A, i32 %B, i8 %cond) {
; CHECK-LABEL: select_or:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: orl %edi, %eax
; CHECK-NEXT: testb $1, %dl
; CHECK-NEXT: cmovel %edi, %eax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: select_or:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: orl %ecx, %eax
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: cmovel %ecx, %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: select_or:
; MCU: # %bb.0: # %entry
; MCU-NEXT: andl $1, %ecx
; MCU-NEXT: negl %ecx
; MCU-NEXT: andl %edx, %ecx
; MCU-NEXT: orl %ecx, %eax
; MCU-NEXT: retl
entry:
%and = and i8 %cond, 1
%cmp10 = icmp eq i8 %and, 0
%0 = or i32 %B, %A
%1 = select i1 %cmp10, i32 %A, i32 %0
ret i32 %1
}
; Equivalent to above, but with icmp ne (and %cond, 1), 1 instead of
; icmp eq (and %cond, 1), 0
define i32 @select_or_b(i32 %A, i32 %B, i8 %cond) {
; CHECK-LABEL: select_or_b:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: orl %edi, %eax
; CHECK-NEXT: testb $1, %dl
; CHECK-NEXT: cmovel %edi, %eax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: select_or_b:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: orl %ecx, %eax
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: cmovel %ecx, %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: select_or_b:
; MCU: # %bb.0: # %entry
; MCU-NEXT: testb $1, %cl
; MCU-NEXT: je .LBB28_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: orl %edx, %eax
; MCU-NEXT: .LBB28_2: # %entry
; MCU-NEXT: retl
entry:
%and = and i8 %cond, 1
%cmp10 = icmp ne i8 %and, 1
%0 = or i32 %B, %A
%1 = select i1 %cmp10, i32 %A, i32 %0
ret i32 %1
}
define i32 @select_or_1(i32 %A, i32 %B, i32 %cond) {
; CHECK-LABEL: select_or_1:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: orl %edi, %eax
; CHECK-NEXT: testb $1, %dl
; CHECK-NEXT: cmovel %edi, %eax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: select_or_1:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: orl %ecx, %eax
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: cmovel %ecx, %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: select_or_1:
; MCU: # %bb.0: # %entry
; MCU-NEXT: andl $1, %ecx
; MCU-NEXT: negl %ecx
; MCU-NEXT: andl %edx, %ecx
; MCU-NEXT: orl %ecx, %eax
; MCU-NEXT: retl
entry:
%and = and i32 %cond, 1
%cmp10 = icmp eq i32 %and, 0
%0 = or i32 %B, %A
%1 = select i1 %cmp10, i32 %A, i32 %0
ret i32 %1
}
; Equivalent to above, but with icmp ne (and %cond, 1), 1 instead of
; icmp eq (and %cond, 1), 0
define i32 @select_or_1b(i32 %A, i32 %B, i32 %cond) {
; CHECK-LABEL: select_or_1b:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: orl %edi, %eax
; CHECK-NEXT: testb $1, %dl
; CHECK-NEXT: cmovel %edi, %eax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: select_or_1b:
; ATHLON: ## %bb.0: ## %entry
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: orl %ecx, %eax
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: cmovel %ecx, %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: select_or_1b:
; MCU: # %bb.0: # %entry
; MCU-NEXT: testb $1, %cl
; MCU-NEXT: je .LBB30_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: orl %edx, %eax
; MCU-NEXT: .LBB30_2: # %entry
; MCU-NEXT: retl
entry:
%and = and i32 %cond, 1
%cmp10 = icmp ne i32 %and, 1
%0 = or i32 %B, %A
%1 = select i1 %cmp10, i32 %A, i32 %0
ret i32 %1
}
define i64 @PR51612(i64 %x, i64 %y) {
; CHECK-LABEL: PR51612:
; CHECK: ## %bb.0:
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: incl %esi
; CHECK-NEXT: incq %rax
; CHECK-NEXT: cmovel %esi, %eax
; CHECK-NEXT: andl 10, %eax
; CHECK-NEXT: retq
;
; ATHLON-LABEL: PR51612:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: incl %edx
; ATHLON-NEXT: addl $1, %eax
; ATHLON-NEXT: adcl $0, %ecx
; ATHLON-NEXT: cmovbl %edx, %eax
; ATHLON-NEXT: andl 10, %eax
; ATHLON-NEXT: xorl %edx, %edx
; ATHLON-NEXT: retl
;
; MCU-LABEL: PR51612:
; MCU: # %bb.0:
; MCU-NEXT: addl $1, %eax
; MCU-NEXT: adcl $0, %edx
; MCU-NEXT: jae .LBB31_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: movl {{[0-9]+}}(%esp), %eax
; MCU-NEXT: incl %eax
; MCU-NEXT: .LBB31_2:
; MCU-NEXT: andl 10, %eax
; MCU-NEXT: xorl %edx, %edx
; MCU-NEXT: retl
%add = add i64 %x, 1
%inc = add i64 %y, 1
%tobool = icmp eq i64 %add, 0
%sel = select i1 %tobool, i64 %inc, i64 %add
%i = load i32, i32* inttoptr (i32 10 to i32*), align 4
%conv = zext i32 %i to i64
%and = and i64 %sel, %conv
ret i64 %and
}
; The next 2 tests are for additional bugs based on PR51612.
declare { i8, i1 } @llvm.uadd.with.overflow.i8(i8, i8) nounwind readnone
declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
define i8 @select_uaddo_common_op0(i8 %a, i8 %b, i8 %c, i1 %cond) {
; GENERIC-LABEL: select_uaddo_common_op0:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: ## kill: def $esi killed $esi def $rsi
; GENERIC-NEXT: ## kill: def $edi killed $edi def $rdi
; GENERIC-NEXT: testb $1, %cl
; GENERIC-NEXT: cmovel %edx, %esi
; GENERIC-NEXT: leal (%rsi,%rdi), %eax
; GENERIC-NEXT: ## kill: def $al killed $al killed $eax
; GENERIC-NEXT: retq
;
; ATOM-LABEL: select_uaddo_common_op0:
; ATOM: ## %bb.0:
; ATOM-NEXT: ## kill: def $esi killed $esi def $rsi
; ATOM-NEXT: testb $1, %cl
; ATOM-NEXT: ## kill: def $edi killed $edi def $rdi
; ATOM-NEXT: cmovel %edx, %esi
; ATOM-NEXT: leal (%rsi,%rdi), %eax
; ATOM-NEXT: ## kill: def $al killed $al killed $eax
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: select_uaddo_common_op0:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movb {{[0-9]+}}(%esp), %al
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %edx
; ATHLON-NEXT: cmovnel %ecx, %edx
; ATHLON-NEXT: addb (%edx), %al
; ATHLON-NEXT: retl
;
; MCU-LABEL: select_uaddo_common_op0:
; MCU: # %bb.0:
; MCU-NEXT: testb $1, {{[0-9]+}}(%esp)
; MCU-NEXT: jne .LBB32_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: movl %ecx, %edx
; MCU-NEXT: .LBB32_2:
; MCU-NEXT: addb %dl, %al
; MCU-NEXT: # kill: def $al killed $al killed $eax
; MCU-NEXT: retl
%ab = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)
%ac = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 %c)
%ab0 = extractvalue { i8, i1 } %ab, 0
%ac0 = extractvalue { i8, i1 } %ac, 0
%sel = select i1 %cond, i8 %ab0, i8 %ac0
ret i8 %sel
}
define i32 @select_uaddo_common_op1(i32 %a, i32 %b, i32 %c, i1 %cond) {
; GENERIC-LABEL: select_uaddo_common_op1:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: ## kill: def $esi killed $esi def $rsi
; GENERIC-NEXT: ## kill: def $edi killed $edi def $rdi
; GENERIC-NEXT: testb $1, %cl
; GENERIC-NEXT: cmovel %edx, %edi
; GENERIC-NEXT: leal (%rdi,%rsi), %eax
; GENERIC-NEXT: retq
;
; ATOM-LABEL: select_uaddo_common_op1:
; ATOM: ## %bb.0:
; ATOM-NEXT: ## kill: def $edi killed $edi def $rdi
; ATOM-NEXT: testb $1, %cl
; ATOM-NEXT: ## kill: def $esi killed $esi def $rsi
; ATOM-NEXT: cmovel %edx, %edi
; ATOM-NEXT: leal (%rdi,%rsi), %eax
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: select_uaddo_common_op1:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: testb $1, {{[0-9]+}}(%esp)
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: leal {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: cmovnel %eax, %ecx
; ATHLON-NEXT: movl (%ecx), %eax
; ATHLON-NEXT: addl {{[0-9]+}}(%esp), %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: select_uaddo_common_op1:
; MCU: # %bb.0:
; MCU-NEXT: testb $1, {{[0-9]+}}(%esp)
; MCU-NEXT: jne .LBB33_2
; MCU-NEXT: # %bb.1:
; MCU-NEXT: movl %ecx, %eax
; MCU-NEXT: .LBB33_2:
; MCU-NEXT: addl %edx, %eax
; MCU-NEXT: retl
%ab = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)
%cb = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %c, i32 %b)
%ab0 = extractvalue { i32, i1 } %ab, 0
%cb0 = extractvalue { i32, i1 } %cb, 0
%sel = select i1 %cond, i32 %ab0, i32 %cb0
ret i32 %sel
}