diff options
| -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,  | 

