summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2018-02-12 21:18:11 +0000
committerCraig Topper <craig.topper@intel.com>2018-02-12 21:18:11 +0000
commit88939fefe80bf65395705949e7598c0a0e224f28 (patch)
tree1eb2fa304426a0756ccb88cd7799051d1b0e228b /llvm/lib
parentefe392351451853285eea864fb70a414bbd9612d (diff)
downloadbcm5719-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.cpp44
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp1
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.h3
-rw-r--r--llvm/lib/Target/X86/X86InstrCompiler.td31
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.td2
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,
OpenPOWER on IntegriCloud