diff options
author | Craig Topper <craig.topper@intel.com> | 2018-02-12 21:18:11 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2018-02-12 21:18:11 +0000 |
commit | 88939fefe80bf65395705949e7598c0a0e224f28 (patch) | |
tree | 1eb2fa304426a0756ccb88cd7799051d1b0e228b /llvm/lib | |
parent | efe392351451853285eea864fb70a414bbd9612d (diff) | |
download | bcm5719-llvm-88939fefe80bf65395705949e7598c0a0e224f28.tar.gz bcm5719-llvm-88939fefe80bf65395705949e7598c0a0e224f28.zip |
[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
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 44 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.h | 3 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrCompiler.td | 31 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 2 |
5 files changed, 43 insertions, 38 deletions
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 35bc01fbe0c..1e9ad7a1b3c 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -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; } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a6477985dec..ccae968696e 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -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"; diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index 78204981465..df82c5a5b82 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -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, diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td index 56c24322e6a..959fca3a03d 100644 --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -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)>; +} diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index f91db56e9ef..c0b0d7f9e5f 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -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, |