diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 21 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.h | 6 | 
2 files changed, 25 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 6306ad52db5..5d7890ee08f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -18078,11 +18078,28 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {    // If it is a splat, check if the argument vector is another splat or a    // build_vector.    if (SVN->isSplat() && SVN->getSplatIndex() < (int)NumElts) { -    SDNode *V = N0.getNode(); +    int SplatIndex = SVN->getSplatIndex(); +    if (TLI.isExtractVecEltCheap(VT, SplatIndex) && +        ISD::isBinaryOp(N0.getNode())) { +      // splat (vector_bo L, R), Index --> +      // splat (scalar_bo (extelt L, Index), (extelt R, Index)) +      SDValue L = N0.getOperand(0), R = N0.getOperand(1); +      SDLoc DL(N); +      EVT EltVT = VT.getScalarType(); +      SDValue Index = DAG.getIntPtrConstant(SplatIndex, DL); +      SDValue ExtL = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, L, Index); +      SDValue ExtR = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, R, Index); +      SDValue NewBO = DAG.getNode(N0.getOpcode(), DL, EltVT, ExtL, ExtR, +                                  N0.getNode()->getFlags()); +      SDValue Insert = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, NewBO); +      SmallVector<int, 16> ZeroMask(VT.getVectorNumElements(), 0); +      return DAG.getVectorShuffle(VT, DL, Insert, DAG.getUNDEF(VT), ZeroMask); +    }      // If this is a bit convert that changes the element type of the vector but      // not the number of vector elements, look through it.  Be careful not to      // look though conversions that change things like v4f32 to v2f64. +    SDNode *V = N0.getNode();      if (V->getOpcode() == ISD::BITCAST) {        SDValue ConvInput = V->getOperand(0);        if (ConvInput.getValueType().isVector() && @@ -18115,7 +18132,7 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {          return N0;        // Canonicalize any other splat as a build_vector. -      const SDValue &Splatted = V->getOperand(SVN->getSplatIndex()); +      SDValue Splatted = V->getOperand(SplatIndex);        SmallVector<SDValue, 8> Ops(NumElts, Splatted);        SDValue NewBV = DAG.getBuildVector(V->getValueType(0), SDLoc(N), Ops); diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index c481de02421..b46fb8ef6fc 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -1074,6 +1074,12 @@ namespace llvm {      /// supported.      bool shouldScalarizeBinop(SDValue) const override; +    /// Extract of a scalar FP value from index 0 of a vector is free. +    bool isExtractVecEltCheap(EVT VT, unsigned Index) const override { +      EVT EltVT = VT.getScalarType(); +      return (EltVT == MVT::f32 || EltVT == MVT::f64) && Index == 0; +    } +      /// Overflow nodes should get combined/lowered to optimal instructions      /// (they should allow eliminating explicit compares by getting flags from      /// math ops).  | 

