diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2019-04-22 22:43:36 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2019-04-22 22:43:36 +0000 |
| commit | bf8aacb7151cf3ed569c4907c934c45244f6914f (patch) | |
| tree | 3e02f7cf65f7b7fab3a8796d767203fac5fb1b99 /llvm/lib | |
| parent | a38b8c8abce0233e7ffc8d9d8de2436505877d59 (diff) | |
| download | bcm5719-llvm-bf8aacb7151cf3ed569c4907c934c45244f6914f.tar.gz bcm5719-llvm-bf8aacb7151cf3ed569c4907c934c45244f6914f.zip | |
[SelectionDAG] move splat util functions up from x86 lowering
This was supposed to be NFC, but the change in SDLoc
definitions causes instruction scheduling changes.
There's nothing x86-specific in this code, and it can
likely be used from DAGCombiner's simplifyVBinOp().
llvm-svn: 358930
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 52 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 57 |
2 files changed, 53 insertions, 56 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index b2de2a4f343..4b21b96c9df 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2300,6 +2300,52 @@ bool SelectionDAG::isSplatValue(SDValue V, bool AllowUndefs) { (AllowUndefs || !UndefElts); } +SDValue SelectionDAG::getSplatSourceVector(SDValue V, int &SplatIdx) { + V = peekThroughExtractSubvectors(V); + + EVT VT = V.getValueType(); + unsigned Opcode = V.getOpcode(); + switch (Opcode) { + default: { + APInt UndefElts; + APInt DemandedElts = APInt::getAllOnesValue(VT.getVectorNumElements()); + if (isSplatValue(V, DemandedElts, UndefElts)) { + // Handle case where all demanded elements are UNDEF. + if (DemandedElts.isSubsetOf(UndefElts)) { + SplatIdx = 0; + return getUNDEF(VT); + } + SplatIdx = (UndefElts & DemandedElts).countTrailingOnes(); + return V; + } + break; + } + case ISD::VECTOR_SHUFFLE: { + // Check if this is a shuffle node doing a splat. + // TODO - remove this and rely purely on SelectionDAG::isSplatValue, + // getTargetVShiftNode currently struggles without the splat source. + auto *SVN = cast<ShuffleVectorSDNode>(V); + if (!SVN->isSplat()) + break; + int Idx = SVN->getSplatIndex(); + int NumElts = V.getValueType().getVectorNumElements(); + SplatIdx = Idx % NumElts; + return V.getOperand(Idx / NumElts); + } + } + + return SDValue(); +} + +SDValue SelectionDAG::getSplatValue(SDValue V) { + int SplatIdx; + if (SDValue SrcVector = getSplatSourceVector(V, SplatIdx)) + return getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(V), + SrcVector.getValueType().getScalarType(), SrcVector, + getIntPtrConstant(SplatIdx, SDLoc(V))); + return SDValue(); +} + /// If a SHL/SRA/SRL node has a constant or splat constant shift amount that /// is less than the element bit-width of the shift node, return it. static const APInt *getValidShiftAmountConstant(SDValue V) { @@ -8585,6 +8631,12 @@ SDValue llvm::peekThroughOneUseBitcasts(SDValue V) { return V; } +SDValue llvm::peekThroughExtractSubvectors(SDValue V) { + while (V.getOpcode() == ISD::EXTRACT_SUBVECTOR) + V = V.getOperand(0); + return V; +} + bool llvm::isBitwiseNot(SDValue V) { if (V.getOpcode() != ISD::XOR) return false; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 2534948bb5c..f13e1147dd9 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5711,13 +5711,6 @@ static SDValue getShuffleVectorZeroOrUndef(SDValue V2, int Idx, return DAG.getVectorShuffle(VT, SDLoc(V2), V1, V2, MaskVec); } -// Peek through EXTRACT_SUBVECTORs - typically used for AVX1 256-bit intops. -static SDValue peekThroughEXTRACT_SUBVECTORs(SDValue V) { - while (V.getOpcode() == ISD::EXTRACT_SUBVECTOR) - V = V.getOperand(0); - return V; -} - static const Constant *getTargetConstantFromNode(SDValue Op) { Op = peekThroughBitcasts(Op); @@ -24722,54 +24715,6 @@ static SDValue LowerScalarImmediateShift(SDValue Op, SelectionDAG &DAG, return SDValue(); } -// If V is a splat value, return the source vector and splat index; -static SDValue IsSplatVector(SDValue V, int &SplatIdx, SelectionDAG &DAG) { - V = peekThroughEXTRACT_SUBVECTORs(V); - - EVT VT = V.getValueType(); - unsigned Opcode = V.getOpcode(); - switch (Opcode) { - default: { - APInt UndefElts; - APInt DemandedElts = APInt::getAllOnesValue(VT.getVectorNumElements()); - if (DAG.isSplatValue(V, DemandedElts, UndefElts)) { - // Handle case where all demanded elements are UNDEF. - if (DemandedElts.isSubsetOf(UndefElts)) { - SplatIdx = 0; - return DAG.getUNDEF(VT); - } - SplatIdx = (UndefElts & DemandedElts).countTrailingOnes(); - return V; - } - break; - } - case ISD::VECTOR_SHUFFLE: { - // Check if this is a shuffle node doing a splat. - // TODO - remove this and rely purely on SelectionDAG::isSplatValue, - // getTargetVShiftNode currently struggles without the splat source. - auto *SVN = cast<ShuffleVectorSDNode>(V); - if (!SVN->isSplat()) - break; - int Idx = SVN->getSplatIndex(); - int NumElts = V.getValueType().getVectorNumElements(); - SplatIdx = Idx % NumElts; - return V.getOperand(Idx / NumElts); - } - } - - return SDValue(); -} - -static SDValue GetSplatValue(SDValue V, const SDLoc &dl, - SelectionDAG &DAG) { - int SplatIdx; - if (SDValue SrcVector = IsSplatVector(V, SplatIdx, DAG)) - return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, - SrcVector.getValueType().getScalarType(), SrcVector, - DAG.getIntPtrConstant(SplatIdx, dl)); - return SDValue(); -} - static SDValue LowerScalarVariableShift(SDValue Op, SelectionDAG &DAG, const X86Subtarget &Subtarget) { MVT VT = Op.getSimpleValueType(); @@ -24780,7 +24725,7 @@ static SDValue LowerScalarVariableShift(SDValue Op, SelectionDAG &DAG, unsigned X86OpcI = getTargetVShiftUniformOpcode(Opcode, false); unsigned X86OpcV = getTargetVShiftUniformOpcode(Opcode, true); - if (SDValue BaseShAmt = GetSplatValue(Amt, dl, DAG)) { + if (SDValue BaseShAmt = DAG.getSplatValue(Amt)) { if (SupportedVectorShiftWithBaseAmnt(VT, Subtarget, Opcode)) { MVT EltVT = VT.getVectorElementType(); assert(EltVT.bitsLE(MVT::i64) && "Unexpected element type!"); |

