mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +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) {
|
||||
ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op1);
|
||||
uint64_t AndRHSVal = AndRHS->getZExtValue();
|
||||
SDValue AndLHS = Op0;
|
||||
if (AndRHS->getZExtValue() == 1 && AndLHS.getOpcode() == ISD::SRL) {
|
||||
|
||||
if (AndRHSVal == 1 && AndLHS.getOpcode() == ISD::SRL) {
|
||||
LHS = AndLHS.getOperand(0);
|
||||
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()) {
|
||||
|
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…
Reference in New Issue
Block a user