mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-19 19:03:50 +00:00
X86: Use btq for bit tests if the immediate can't be encoded in 32 bits.
Before: movabsq $4294967296, %rax ## encoding: [0x48,0xb8,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00] testq %rax, %rdi ## encoding: [0x48,0x85,0xf8] jne LBB0_2 ## encoding: [0x75,A] After: btq $32, %rdi ## encoding: [0x48,0x0f,0xba,0xe7,0x20] jb LBB0_2 ## encoding: [0x72,A] btq is usually slower than testq because it doesn't fuse with the jump, but here we're better off saving one register and a giant movabsq. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145103 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e4513b1fc5
commit
f238f50aaf
@ -8543,11 +8543,19 @@ SDValue X86TargetLowering::LowerToBT(SDValue And, ISD::CondCode CC,
|
|||||||
}
|
}
|
||||||
} else if (Op1.getOpcode() == ISD::Constant) {
|
} else if (Op1.getOpcode() == ISD::Constant) {
|
||||||
ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op1);
|
ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op1);
|
||||||
|
uint64_t AndRHSVal = AndRHS->getZExtValue();
|
||||||
SDValue AndLHS = Op0;
|
SDValue AndLHS = Op0;
|
||||||
if (AndRHS->getZExtValue() == 1 && AndLHS.getOpcode() == ISD::SRL) {
|
|
||||||
|
if (AndRHSVal == 1 && AndLHS.getOpcode() == ISD::SRL) {
|
||||||
LHS = AndLHS.getOperand(0);
|
LHS = AndLHS.getOperand(0);
|
||||||
RHS = AndLHS.getOperand(1);
|
RHS = AndLHS.getOperand(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use BT if the immediate can't be encoded in a TEST instruction.
|
||||||
|
if (!isUInt<32>(AndRHSVal) && isPowerOf2_64(AndRHSVal)) {
|
||||||
|
LHS = AndLHS;
|
||||||
|
RHS = DAG.getConstant(Log2_64_Ceil(AndRHSVal), LHS.getValueType());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LHS.getNode()) {
|
if (LHS.getNode()) {
|
||||||
|
35
test/CodeGen/X86/btq.ll
Normal file
35
test/CodeGen/X86/btq.ll
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
; RUN: llc < %s -march=x86-64 | FileCheck %s
|
||||||
|
|
||||||
|
declare void @bar()
|
||||||
|
|
||||||
|
define void @test1(i64 %foo) nounwind {
|
||||||
|
%and = and i64 %foo, 4294967296
|
||||||
|
%tobool = icmp eq i64 %and, 0
|
||||||
|
br i1 %tobool, label %if.end, label %if.then
|
||||||
|
|
||||||
|
; CHECK: test1:
|
||||||
|
; CHECK: btq $32
|
||||||
|
|
||||||
|
if.then:
|
||||||
|
tail call void @bar() nounwind
|
||||||
|
br label %if.end
|
||||||
|
|
||||||
|
if.end:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @test2(i64 %foo) nounwind {
|
||||||
|
%and = and i64 %foo, 2147483648
|
||||||
|
%tobool = icmp eq i64 %and, 0
|
||||||
|
br i1 %tobool, label %if.end, label %if.then
|
||||||
|
|
||||||
|
; CHECK: test2:
|
||||||
|
; CHECK: testl $-2147483648
|
||||||
|
|
||||||
|
if.then:
|
||||||
|
tail call void @bar() nounwind
|
||||||
|
br label %if.end
|
||||||
|
|
||||||
|
if.end:
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user