forked from OSchip/llvm-project
[X86] Simplify X86DAGToDAGISel::matchBEXTRFromAnd by creating an X86ISD::BEXTR node and calling Select. Add isel patterns to recognize this node.
This removes a bunch of special case code for selecting the immediate and folding loads. llvm-svn: 324939
This commit is contained in:
parent
efe3923514
commit
88939fefe8
|
@ -2437,44 +2437,12 @@ bool X86DAGToDAGISel::matchBEXTRFromAnd(SDNode *Node) {
|
|||
if (Shift + MaskSize > NVT.getSizeInBits())
|
||||
return false;
|
||||
|
||||
SDValue New = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
|
||||
unsigned ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
|
||||
unsigned MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
|
||||
|
||||
// BMI requires the immediate to placed in a register.
|
||||
if (!Subtarget->hasTBM()) {
|
||||
ROpc = NVT == MVT::i64 ? X86::BEXTR64rr : X86::BEXTR32rr;
|
||||
MOpc = NVT == MVT::i64 ? X86::BEXTR64rm : X86::BEXTR32rm;
|
||||
New = SDValue(CurDAG->getMachineNode(X86::MOV32ri, dl, NVT, New), 0);
|
||||
if (NVT == MVT::i64) {
|
||||
New =
|
||||
SDValue(CurDAG->getMachineNode(
|
||||
TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
|
||||
CurDAG->getTargetConstant(0, dl, MVT::i64), New,
|
||||
CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
MachineSDNode *NewNode;
|
||||
SDValue Input = N0->getOperand(0);
|
||||
SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
|
||||
if (tryFoldLoad(Node, N0.getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
|
||||
SDValue Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, New, Input.getOperand(0) };
|
||||
SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
|
||||
NewNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
|
||||
// Update the chain.
|
||||
ReplaceUses(Input.getValue(1), SDValue(NewNode, 1));
|
||||
// Record the mem-refs
|
||||
MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
|
||||
MemOp[0] = cast<LoadSDNode>(Input)->getMemOperand();
|
||||
NewNode->setMemRefs(MemOp, MemOp + 1);
|
||||
} else {
|
||||
NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, Input, New);
|
||||
}
|
||||
|
||||
ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 0));
|
||||
CurDAG->RemoveDeadNode(Node);
|
||||
// Create a BEXTR node and run it through selection.
|
||||
SDValue C = CurDAG->getConstant(Shift | (MaskSize << 8), dl, NVT);
|
||||
SDValue New = CurDAG->getNode(X86ISD::BEXTR, dl, NVT,
|
||||
N0->getOperand(0), C);
|
||||
ReplaceNode(Node, New.getNode());
|
||||
SelectCode(New.getNode());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -25330,6 +25330,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||
case X86ISD::OR: return "X86ISD::OR";
|
||||
case X86ISD::XOR: return "X86ISD::XOR";
|
||||
case X86ISD::AND: return "X86ISD::AND";
|
||||
case X86ISD::BEXTR: return "X86ISD::BEXTR";
|
||||
case X86ISD::MUL_IMM: return "X86ISD::MUL_IMM";
|
||||
case X86ISD::MOVMSK: return "X86ISD::MOVMSK";
|
||||
case X86ISD::PTEST: return "X86ISD::PTEST";
|
||||
|
|
|
@ -346,6 +346,9 @@ namespace llvm {
|
|||
ADD, SUB, ADC, SBB, SMUL,
|
||||
INC, DEC, OR, XOR, AND,
|
||||
|
||||
// Bit field extract.
|
||||
BEXTR,
|
||||
|
||||
// LOW, HI, FLAGS = umul LHS, RHS.
|
||||
UMUL,
|
||||
|
||||
|
|
|
@ -2011,3 +2011,34 @@ def : Pat<(cttz_zero_undef (loadi64 addr:$src)), (BSF64rm addr:$src)>;
|
|||
let Predicates = [HasMOVBE] in {
|
||||
def : Pat<(bswap GR16:$src), (ROL16ri GR16:$src, (i8 8))>;
|
||||
}
|
||||
|
||||
// These patterns are selected by some custom code in X86ISelDAGToDAG.cpp that
|
||||
// custom combines and+srl into BEXTR. We use these patterns to avoid a bunch
|
||||
// of manual code for folding loads.
|
||||
let Predicates = [HasBMI, NoTBM] in {
|
||||
def : Pat<(X86bextr GR32:$src1, (i32 imm:$src2)),
|
||||
(BEXTR32rr GR32:$src1, (MOV32ri imm:$src2))>;
|
||||
def : Pat<(X86bextr (loadi32 addr:$src1), (i32 imm:$src2)),
|
||||
(BEXTR32rm addr:$src1, (MOV32ri imm:$src2))>;
|
||||
def : Pat<(X86bextr GR64:$src1, mov64imm32:$src2),
|
||||
(BEXTR64rr GR64:$src1,
|
||||
(SUBREG_TO_REG (i64 0),
|
||||
(MOV32ri64 mov64imm32:$src2),
|
||||
sub_32bit))>;
|
||||
def : Pat<(X86bextr (loadi64 addr:$src1), mov64imm32:$src2),
|
||||
(BEXTR64rm addr:$src1,
|
||||
(SUBREG_TO_REG (i64 0),
|
||||
(MOV32ri64 mov64imm32:$src2),
|
||||
sub_32bit))>;
|
||||
} // HasBMI, NoTBM
|
||||
|
||||
let Predicates = [HasTBM] in {
|
||||
def : Pat<(X86bextr GR32:$src1, (i32 imm:$src2)),
|
||||
(BEXTRI32ri GR32:$src1, imm:$src2)>;
|
||||
def : Pat<(X86bextr (loadi32 addr:$src1), (i32 imm:$src2)),
|
||||
(BEXTRI32mi addr:$src1, imm:$src2)>;
|
||||
def : Pat<(X86bextr GR64:$src1, i64immSExt32:$src2),
|
||||
(BEXTRI64ri GR64:$src1, i64immSExt32:$src2)>;
|
||||
def : Pat<(X86bextr (loadi64 addr:$src1), i64immSExt32:$src2),
|
||||
(BEXTRI64mi addr:$src1, i64immSExt32:$src2)>;
|
||||
}
|
||||
|
|
|
@ -281,6 +281,8 @@ def X86lock_dec : SDNode<"X86ISD::LDEC", SDTLockUnaryArithWithFlags,
|
|||
[SDNPHasChain, SDNPMayStore, SDNPMayLoad,
|
||||
SDNPMemOperand]>;
|
||||
|
||||
def X86bextr : SDNode<"X86ISD::BEXTR", SDTIntBinOp>;
|
||||
|
||||
def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
|
||||
|
||||
def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDT_X86WIN_ALLOCA,
|
||||
|
|
Loading…
Reference in New Issue