mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Add a simple pattern for matching 'bt'.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61426 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f1e9fd5676
commit
e55484eb45
@ -5017,16 +5017,48 @@ SDValue X86TargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) {
|
||||
|
||||
SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
|
||||
assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer");
|
||||
SDValue Cond;
|
||||
SDValue Op0 = Op.getOperand(0);
|
||||
SDValue Op1 = Op.getOperand(1);
|
||||
SDValue CC = Op.getOperand(2);
|
||||
bool isFP = Op.getOperand(1).getValueType().isFloatingPoint();
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
|
||||
|
||||
// Lower (X & (1 << N)) == 0 to BT.
|
||||
// Lower ((X >>u N) & 1) != 0 to BT.
|
||||
// Lower ((X >>s N) & 1) != 0 to BT.
|
||||
// FIXME: Is i386 or later or available only on some chips?
|
||||
if (Op0.getOpcode() == ISD::AND && Op1.getOpcode() == ISD::Constant &&
|
||||
Op0.getOperand(1).getOpcode() == ISD::Constant &&
|
||||
(CC == ISD::SETEQ || CC == ISD::SETNE)) {
|
||||
ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op0.getOperand(1));
|
||||
ConstantSDNode *CmpRHS = cast<ConstantSDNode>(Op1);
|
||||
SDValue AndLHS = Op0.getOperand(0);
|
||||
if (CmpRHS->getZExtValue() == 0 && AndRHS->getZExtValue() == 1 &&
|
||||
AndLHS.getOpcode() == ISD::SRL) {
|
||||
SDValue LHS = AndLHS.getOperand(0);
|
||||
SDValue RHS = AndLHS.getOperand(1);
|
||||
|
||||
unsigned X86CC = TranslateX86CC(cast<CondCodeSDNode>(CC)->get(), isFP,
|
||||
Op0, Op1, DAG);
|
||||
// If LHS is i8, promote it to i16 with any_extend. There is no i8 BT
|
||||
// instruction. Since the shift amount is in-range-or-undefined, we know
|
||||
// that doing a bittest on the i16 value is ok. We extend to i32 because
|
||||
// the encoding for the i16 version is larger than the i32 version.
|
||||
if (LHS.getValueType() == MVT::i8)
|
||||
LHS = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, LHS);
|
||||
|
||||
// If the operand types disagree, extend the shift amount to match. Since
|
||||
// BT ignores high bits (like shifts) we can use anyextend.
|
||||
if (LHS.getValueType() != RHS.getValueType())
|
||||
RHS = DAG.getNode(ISD::ANY_EXTEND, LHS.getValueType(), RHS);
|
||||
|
||||
SDValue BT = DAG.getNode(X86ISD::BT, MVT::i32, LHS, RHS);
|
||||
unsigned Cond = CC == ISD::SETEQ ? X86::COND_NC : X86::COND_C;
|
||||
return DAG.getNode(X86ISD::SETCC, MVT::i8,
|
||||
DAG.getConstant(Cond, MVT::i8), BT);
|
||||
}
|
||||
}
|
||||
|
||||
bool isFP = Op.getOperand(1).getValueType().isFloatingPoint();
|
||||
unsigned X86CC = TranslateX86CC(CC, isFP, Op0, Op1, DAG);
|
||||
|
||||
Cond = DAG.getNode(X86ISD::CMP, MVT::i32, Op0, Op1);
|
||||
SDValue Cond = DAG.getNode(X86ISD::CMP, MVT::i32, Op0, Op1);
|
||||
return DAG.getNode(X86ISD::SETCC, MVT::i8,
|
||||
DAG.getConstant(X86CC, MVT::i8), Cond);
|
||||
}
|
||||
@ -5219,12 +5251,15 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) {
|
||||
|
||||
if (Cond.getOpcode() == ISD::SETCC)
|
||||
Cond = LowerSETCC(Cond, DAG);
|
||||
#if 0
|
||||
// FIXME: LowerXALUO doesn't handle these!!
|
||||
else if (Cond.getOpcode() == X86ISD::ADD ||
|
||||
Cond.getOpcode() == X86ISD::SUB ||
|
||||
Cond.getOpcode() == X86ISD::SMUL ||
|
||||
Cond.getOpcode() == X86ISD::UMUL)
|
||||
Cond = LowerXALUO(Cond, DAG);
|
||||
|
||||
#endif
|
||||
|
||||
// If condition flag is set by a X86ISD::CMP, then use it as the condition
|
||||
// setting operand in place of the X86ISD::SETCC.
|
||||
if (Cond.getOpcode() == X86ISD::SETCC) {
|
||||
@ -5232,7 +5267,8 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) {
|
||||
|
||||
SDValue Cmp = Cond.getOperand(1);
|
||||
unsigned Opc = Cmp.getOpcode();
|
||||
if (isX86LogicalCmp(Opc)) {
|
||||
// FIXME: WHY THE SPECIAL CASING OF LogicalCmp??
|
||||
if (isX86LogicalCmp(Opc) || Opc == X86ISD::BT) {
|
||||
Cond = Cmp;
|
||||
addTest = false;
|
||||
} else {
|
||||
@ -5240,8 +5276,8 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) {
|
||||
default: break;
|
||||
case X86::COND_O:
|
||||
case X86::COND_C:
|
||||
// These can only come from an arithmetic instruction with overflow, e.g.
|
||||
// SADDO, UADDO.
|
||||
// These can only come from an arithmetic instruction with overflow,
|
||||
// e.g. SADDO, UADDO.
|
||||
Cond = Cond.getNode()->getOperand(1);
|
||||
addTest = false;
|
||||
break;
|
||||
|
20
test/CodeGen/X86/bt.ll
Normal file
20
test/CodeGen/X86/bt.ll
Normal file
@ -0,0 +1,20 @@
|
||||
; RUN: llvm-as < %s | llc | grep btl
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
target triple = "i386-apple-darwin8"
|
||||
|
||||
define void @test2(i32 %x, i32 %n) nounwind {
|
||||
entry:
|
||||
%tmp29 = lshr i32 %x, %n ; <i32> [#uses=1]
|
||||
%tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1]
|
||||
%tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1]
|
||||
br i1 %tmp4, label %bb, label %UnifiedReturnBlock
|
||||
|
||||
bb: ; preds = %entry
|
||||
call void @foo()
|
||||
ret void
|
||||
|
||||
UnifiedReturnBlock: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @foo()
|
Loading…
Reference in New Issue
Block a user