mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-23 04:52:54 +02:00
702b88ddc2
Summary: Same idea as D48529, but restricted to X86 and done very late to avoid any surprises where subtract might be better for DAG combining. This seems like the safest way to do this trick. And we consider doing it as a DAG combine later. Reviewers: spatel, RKSimon Reviewed By: spatel Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D48557 llvm-svn: 335575
282 lines
7.6 KiB
LLVM
282 lines
7.6 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc -mtriple=x86_64-unknown-unknown -verify-machineinstrs < %s | FileCheck -enable-var-scope %s
|
|
|
|
define i32 @select_and1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: select_and1:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: xorl %eax, %eax
|
|
; CHECK-NEXT: cmpl $11, %edi
|
|
; CHECK-NEXT: cmovgel %esi, %eax
|
|
; CHECK-NEXT: retq
|
|
%c = icmp slt i32 %x, 11
|
|
%s = select i1 %c, i32 0, i32 -1
|
|
%a = and i32 %y, %s
|
|
ret i32 %a
|
|
}
|
|
|
|
define i32 @select_and2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: select_and2:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: xorl %eax, %eax
|
|
; CHECK-NEXT: cmpl $11, %edi
|
|
; CHECK-NEXT: cmovgel %esi, %eax
|
|
; CHECK-NEXT: retq
|
|
%c = icmp slt i32 %x, 11
|
|
%s = select i1 %c, i32 0, i32 -1
|
|
%a = and i32 %s, %y
|
|
ret i32 %a
|
|
}
|
|
|
|
define i32 @select_and3(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: select_and3:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: xorl %eax, %eax
|
|
; CHECK-NEXT: cmpl $11, %edi
|
|
; CHECK-NEXT: cmovll %esi, %eax
|
|
; CHECK-NEXT: retq
|
|
%c = icmp slt i32 %x, 11
|
|
%s = select i1 %c, i32 -1, i32 0
|
|
%a = and i32 %y, %s
|
|
ret i32 %a
|
|
}
|
|
|
|
define <4 x i32> @select_and_v4(i32 %x, <4 x i32> %y) {
|
|
; CHECK-LABEL: select_and_v4:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpl $11, %edi
|
|
; CHECK-NEXT: xorps %xmm1, %xmm1
|
|
; CHECK-NEXT: jl .LBB3_2
|
|
; CHECK-NEXT: # %bb.1:
|
|
; CHECK-NEXT: movaps %xmm0, %xmm1
|
|
; CHECK-NEXT: .LBB3_2:
|
|
; CHECK-NEXT: movaps %xmm1, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%c = icmp slt i32 %x, 11
|
|
%s = select i1 %c, <4 x i32> zeroinitializer, <4 x i32><i32 -1, i32 -1, i32 -1, i32 -1>
|
|
%a = and <4 x i32> %s, %y
|
|
ret <4 x i32> %a
|
|
}
|
|
|
|
define i32 @select_or1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: select_or1:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpl $11, %edi
|
|
; CHECK-NEXT: movl $-1, %eax
|
|
; CHECK-NEXT: cmovll %esi, %eax
|
|
; CHECK-NEXT: retq
|
|
%c = icmp slt i32 %x, 11
|
|
%s = select i1 %c, i32 0, i32 -1
|
|
%a = or i32 %y, %s
|
|
ret i32 %a
|
|
}
|
|
|
|
define i32 @select_or2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: select_or2:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpl $11, %edi
|
|
; CHECK-NEXT: movl $-1, %eax
|
|
; CHECK-NEXT: cmovll %esi, %eax
|
|
; CHECK-NEXT: retq
|
|
%c = icmp slt i32 %x, 11
|
|
%s = select i1 %c, i32 0, i32 -1
|
|
%a = or i32 %s, %y
|
|
ret i32 %a
|
|
}
|
|
|
|
define i32 @select_or3(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: select_or3:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpl $11, %edi
|
|
; CHECK-NEXT: movl $-1, %eax
|
|
; CHECK-NEXT: cmovgel %esi, %eax
|
|
; CHECK-NEXT: retq
|
|
%c = icmp slt i32 %x, 11
|
|
%s = select i1 %c, i32 -1, i32 0
|
|
%a = or i32 %y, %s
|
|
ret i32 %a
|
|
}
|
|
|
|
define <4 x i32> @select_or_v4(i32 %x, <4 x i32> %y) {
|
|
; CHECK-LABEL: select_or_v4:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpl $11, %edi
|
|
; CHECK-NEXT: jl .LBB7_2
|
|
; CHECK-NEXT: # %bb.1:
|
|
; CHECK-NEXT: pcmpeqd %xmm0, %xmm0
|
|
; CHECK-NEXT: .LBB7_2:
|
|
; CHECK-NEXT: retq
|
|
%c = icmp slt i32 %x, 11
|
|
%s = select i1 %c, <4 x i32> zeroinitializer, <4 x i32><i32 -1, i32 -1, i32 -1, i32 -1>
|
|
%a = or <4 x i32> %s, %y
|
|
ret <4 x i32> %a
|
|
}
|
|
|
|
define i32 @sel_constants_sub_constant_sel_constants(i1 %cond) {
|
|
; CHECK-LABEL: sel_constants_sub_constant_sel_constants:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: movl $9, %ecx
|
|
; CHECK-NEXT: movl $2, %eax
|
|
; CHECK-NEXT: cmovnel %ecx, %eax
|
|
; CHECK-NEXT: retq
|
|
%sel = select i1 %cond, i32 -4, i32 3
|
|
%bo = sub i32 5, %sel
|
|
ret i32 %bo
|
|
}
|
|
|
|
define i32 @sdiv_constant_sel_constants(i1 %cond) {
|
|
; CHECK-LABEL: sdiv_constant_sel_constants:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: notb %dil
|
|
; CHECK-NEXT: movzbl %dil, %eax
|
|
; CHECK-NEXT: andl $1, %eax
|
|
; CHECK-NEXT: leal (%rax,%rax,4), %eax
|
|
; CHECK-NEXT: retq
|
|
%sel = select i1 %cond, i32 121, i32 23
|
|
%bo = sdiv i32 120, %sel
|
|
ret i32 %bo
|
|
}
|
|
|
|
define i32 @udiv_constant_sel_constants(i1 %cond) {
|
|
; CHECK-LABEL: udiv_constant_sel_constants:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: notb %dil
|
|
; CHECK-NEXT: movzbl %dil, %eax
|
|
; CHECK-NEXT: andl $1, %eax
|
|
; CHECK-NEXT: leal (%rax,%rax,4), %eax
|
|
; CHECK-NEXT: retq
|
|
%sel = select i1 %cond, i32 -4, i32 23
|
|
%bo = udiv i32 120, %sel
|
|
ret i32 %bo
|
|
}
|
|
|
|
define i32 @srem_constant_sel_constants(i1 %cond) {
|
|
; CHECK-LABEL: srem_constant_sel_constants:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: movl $120, %ecx
|
|
; CHECK-NEXT: movl $5, %eax
|
|
; CHECK-NEXT: cmovnel %ecx, %eax
|
|
; CHECK-NEXT: retq
|
|
%sel = select i1 %cond, i32 121, i32 23
|
|
%bo = srem i32 120, %sel
|
|
ret i32 %bo
|
|
}
|
|
|
|
define i32 @urem_constant_sel_constants(i1 %cond) {
|
|
; CHECK-LABEL: urem_constant_sel_constants:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: movl $120, %ecx
|
|
; CHECK-NEXT: movl $5, %eax
|
|
; CHECK-NEXT: cmovnel %ecx, %eax
|
|
; CHECK-NEXT: retq
|
|
%sel = select i1 %cond, i32 -4, i32 23
|
|
%bo = urem i32 120, %sel
|
|
ret i32 %bo
|
|
}
|
|
|
|
define i32 @sel_constants_shl_constant(i1 %cond) {
|
|
; CHECK-LABEL: sel_constants_shl_constant:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: notb %dil
|
|
; CHECK-NEXT: movzbl %dil, %eax
|
|
; CHECK-NEXT: andl $1, %eax
|
|
; CHECK-NEXT: orl $2, %eax
|
|
; CHECK-NEXT: shll $8, %eax
|
|
; CHECK-NEXT: retq
|
|
%sel = select i1 %cond, i32 2, i32 3
|
|
%bo = shl i32 %sel, 8
|
|
ret i32 %bo
|
|
}
|
|
|
|
define i32 @shl_constant_sel_constants(i1 %cond) {
|
|
; CHECK-LABEL: shl_constant_sel_constants:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: andb $1, %dil
|
|
; CHECK-NEXT: xorb $3, %dil
|
|
; CHECK-NEXT: movl $1, %eax
|
|
; CHECK-NEXT: movl %edi, %ecx
|
|
; CHECK-NEXT: shll %cl, %eax
|
|
; CHECK-NEXT: retq
|
|
%sel = select i1 %cond, i32 2, i32 3
|
|
%bo = shl i32 1, %sel
|
|
ret i32 %bo
|
|
}
|
|
|
|
define i32 @lshr_constant_sel_constants(i1 %cond) {
|
|
; CHECK-LABEL: lshr_constant_sel_constants:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: andb $1, %dil
|
|
; CHECK-NEXT: xorb $3, %dil
|
|
; CHECK-NEXT: movl $64, %eax
|
|
; CHECK-NEXT: movl %edi, %ecx
|
|
; CHECK-NEXT: shrl %cl, %eax
|
|
; CHECK-NEXT: retq
|
|
%sel = select i1 %cond, i32 2, i32 3
|
|
%bo = lshr i32 64, %sel
|
|
ret i32 %bo
|
|
}
|
|
|
|
define i32 @ashr_constant_sel_constants(i1 %cond) {
|
|
; CHECK-LABEL: ashr_constant_sel_constants:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: andb $1, %dil
|
|
; CHECK-NEXT: xorb $3, %dil
|
|
; CHECK-NEXT: movl $128, %eax
|
|
; CHECK-NEXT: movl %edi, %ecx
|
|
; CHECK-NEXT: shrl %cl, %eax
|
|
; CHECK-NEXT: retq
|
|
%sel = select i1 %cond, i32 2, i32 3
|
|
%bo = ashr i32 128, %sel
|
|
ret i32 %bo
|
|
}
|
|
|
|
define double @fsub_constant_sel_constants(i1 %cond) {
|
|
; CHECK-LABEL: fsub_constant_sel_constants:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: jne .LBB17_1
|
|
; CHECK-NEXT: # %bb.2:
|
|
; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: .LBB17_1:
|
|
; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; CHECK-NEXT: retq
|
|
%sel = select i1 %cond, double -4.0, double 23.3
|
|
%bo = fsub double 5.1, %sel
|
|
ret double %bo
|
|
}
|
|
|
|
define double @fdiv_constant_sel_constants(i1 %cond) {
|
|
; CHECK-LABEL: fdiv_constant_sel_constants:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: jne .LBB18_1
|
|
; CHECK-NEXT: # %bb.2:
|
|
; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: .LBB18_1:
|
|
; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; CHECK-NEXT: retq
|
|
%sel = select i1 %cond, double -4.0, double 23.3
|
|
%bo = fdiv double 5.1, %sel
|
|
ret double %bo
|
|
}
|
|
|
|
define double @frem_constant_sel_constants(i1 %cond) {
|
|
; CHECK-LABEL: frem_constant_sel_constants:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: jne .LBB19_1
|
|
; CHECK-NEXT: # %bb.2:
|
|
; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: .LBB19_1:
|
|
; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; CHECK-NEXT: retq
|
|
%sel = select i1 %cond, double -4.0, double 23.3
|
|
%bo = frem double 5.1, %sel
|
|
ret double %bo
|
|
}
|