diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2019-09-08 21:38:33 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2019-09-08 21:38:33 +0000 |
commit | e0ea746215c88a713680c32f4589a918e19f385d (patch) | |
tree | 812d9cdad1037a5c3e80a0285398270b2f69b599 /llvm/lib/Target | |
parent | 139a9d6c0e0d872f0f41f94f621c616d8459817a (diff) | |
download | bcm5719-llvm-e0ea746215c88a713680c32f4589a918e19f385d.tar.gz bcm5719-llvm-e0ea746215c88a713680c32f4589a918e19f385d.zip |
[X86][SSE] SimplifyDemandedVectorEltsForTargetNode - add faux shuffle support.
This patch decodes target and faux shuffles with getTargetShuffleInputs - a reduced version of resolveTargetShuffleInputs that doesn't resolve SM_SentinelZero cases, so we can correctly remove zero vectors if they aren't demanded.
llvm-svn: 371353
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index c164da784e4..2fa368764a5 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -6643,7 +6643,8 @@ static bool getTargetShuffleMask(SDNode *N, MVT VT, bool AllowSentinelZero, /// Returns true if the target shuffle mask was decoded. static bool setTargetShuffleZeroElements(SDValue N, SmallVectorImpl<int> &Mask, - SmallVectorImpl<SDValue> &Ops) { + SmallVectorImpl<SDValue> &Ops, + bool ResolveZero = true) { bool IsUnary; if (!isTargetShuffle(N.getOpcode())) return false; @@ -6699,7 +6700,7 @@ static bool setTargetShuffleZeroElements(SDValue N, int Idx = M / Scale; if (Idx != 0 && !VT.isFloatingPoint()) Mask[i] = SM_SentinelUndef; - else if (Idx == 0 && X86::isZeroNode(V.getOperand(0))) + else if (ResolveZero && Idx == 0 && X86::isZeroNode(V.getOperand(0))) Mask[i] = SM_SentinelZero; continue; } @@ -6708,7 +6709,7 @@ static bool setTargetShuffleZeroElements(SDValue N, if (IsSrcConstant[SrcIdx]) { if (UndefSrcElts[SrcIdx][M]) Mask[i] = SM_SentinelUndef; - else if (SrcEltBits[SrcIdx][M] == 0) + else if (ResolveZero && SrcEltBits[SrcIdx][M] == 0) Mask[i] = SM_SentinelZero; } } @@ -6719,10 +6720,12 @@ static bool setTargetShuffleZeroElements(SDValue N, } // Forward declaration (for getFauxShuffleMask recursive check). +// TODO: Use DemandedElts variant. static bool resolveTargetShuffleInputs(SDValue Op, SmallVectorImpl<SDValue> &Inputs, SmallVectorImpl<int> &Mask, - SelectionDAG &DAG, unsigned Depth); + SelectionDAG &DAG, unsigned Depth, + bool ResolveZero); // Attempt to decode ops that could be represented as a shuffle mask. // The decoded shuffle mask may contain a different number of elements to the @@ -6730,7 +6733,8 @@ static bool resolveTargetShuffleInputs(SDValue Op, static bool getFauxShuffleMask(SDValue N, const APInt &DemandedElts, SmallVectorImpl<int> &Mask, SmallVectorImpl<SDValue> &Ops, - SelectionDAG &DAG, unsigned Depth) { + SelectionDAG &DAG, unsigned Depth, + bool ResolveZero) { Mask.clear(); Ops.clear(); @@ -6824,8 +6828,10 @@ static bool getFauxShuffleMask(SDValue N, const APInt &DemandedElts, return false; SmallVector<int, 64> SrcMask0, SrcMask1; SmallVector<SDValue, 2> SrcInputs0, SrcInputs1; - if (!resolveTargetShuffleInputs(N0, SrcInputs0, SrcMask0, DAG, Depth + 1) || - !resolveTargetShuffleInputs(N1, SrcInputs1, SrcMask1, DAG, Depth + 1)) + if (!resolveTargetShuffleInputs(N0, SrcInputs0, SrcMask0, DAG, Depth + 1, + ResolveZero) || + !resolveTargetShuffleInputs(N1, SrcInputs1, SrcMask1, DAG, Depth + 1, + ResolveZero)) return false; int MaskSize = std::max(SrcMask0.size(), SrcMask1.size()); SmallVector<int, 64> Mask0, Mask1; @@ -6875,7 +6881,7 @@ static bool getFauxShuffleMask(SDValue N, const APInt &DemandedElts, SmallVector<int, 64> SubMask; SmallVector<SDValue, 2> SubInputs; if (!resolveTargetShuffleInputs(peekThroughOneUseBitcasts(Sub), SubInputs, - SubMask, DAG, Depth + 1)) + SubMask, DAG, Depth + 1, ResolveZero)) return false; if (SubMask.size() != NumSubElts) { assert(((SubMask.size() % NumSubElts) == 0 || @@ -7152,6 +7158,21 @@ static void resolveTargetShuffleInputsAndMask(SmallVectorImpl<SDValue> &Inputs, } /// Calls setTargetShuffleZeroElements to resolve a target shuffle mask's inputs +/// and set the SM_SentinelUndef and SM_SentinelZero values. +/// Returns true if the target shuffle mask was decoded. +static bool getTargetShuffleInputs(SDValue Op, const APInt &DemandedElts, + SmallVectorImpl<SDValue> &Inputs, + SmallVectorImpl<int> &Mask, + SelectionDAG &DAG, unsigned Depth, + bool ResolveZero) { + if (!setTargetShuffleZeroElements(Op, Mask, Inputs, ResolveZero)) + if (!getFauxShuffleMask(Op, DemandedElts, Mask, Inputs, DAG, Depth, + ResolveZero)) + return false; + return true; +} + +/// Calls setTargetShuffleZeroElements to resolve a target shuffle mask's inputs /// and set the SM_SentinelUndef and SM_SentinelZero values. Then check the /// remaining input indices in case we now have a unary shuffle and adjust the /// inputs accordingly. @@ -7159,9 +7180,11 @@ static void resolveTargetShuffleInputsAndMask(SmallVectorImpl<SDValue> &Inputs, static bool resolveTargetShuffleInputs(SDValue Op, const APInt &DemandedElts, SmallVectorImpl<SDValue> &Inputs, SmallVectorImpl<int> &Mask, - SelectionDAG &DAG, unsigned Depth) { - if (!setTargetShuffleZeroElements(Op, Mask, Inputs)) - if (!getFauxShuffleMask(Op, DemandedElts, Mask, Inputs, DAG, Depth)) + SelectionDAG &DAG, unsigned Depth, + bool ResolveZero) { + if (!setTargetShuffleZeroElements(Op, Mask, Inputs, ResolveZero)) + if (!getFauxShuffleMask(Op, DemandedElts, Mask, Inputs, DAG, Depth, + ResolveZero)) return false; resolveTargetShuffleInputsAndMask(Inputs, Mask); @@ -7171,10 +7194,12 @@ static bool resolveTargetShuffleInputs(SDValue Op, const APInt &DemandedElts, static bool resolveTargetShuffleInputs(SDValue Op, SmallVectorImpl<SDValue> &Inputs, SmallVectorImpl<int> &Mask, - SelectionDAG &DAG, unsigned Depth) { + SelectionDAG &DAG, unsigned Depth, + bool ResolveZero = true) { unsigned NumElts = Op.getValueType().getVectorNumElements(); APInt DemandedElts = APInt::getAllOnesValue(NumElts); - return resolveTargetShuffleInputs(Op, DemandedElts, Inputs, Mask, DAG, Depth); + return resolveTargetShuffleInputs(Op, DemandedElts, Inputs, Mask, DAG, Depth, + ResolveZero); } /// Returns the scalar element that will make up the ith @@ -34666,22 +34691,19 @@ bool X86TargetLowering::SimplifyDemandedVectorEltsForTargetNode( } } - // Simplify target shuffles. - // TODO: Use resolveTargetShuffleInputs. - if (!isTargetShuffle(Opc) || !VT.isSimple()) - return false; - - // Get target shuffle mask. - bool IsUnary; + // Get target/faux shuffle mask. SmallVector<int, 64> OpMask; SmallVector<SDValue, 2> OpInputs; - if (!getTargetShuffleMask(Op.getNode(), VT.getSimpleVT(), true, OpInputs, - OpMask, IsUnary)) + if (!VT.isSimple() || !getTargetShuffleInputs(Op, DemandedElts, OpInputs, + OpMask, TLO.DAG, Depth, false)) return false; - // Shuffle inputs must be the same type as the result. - if (llvm::any_of(OpInputs, - [VT](SDValue V) { return VT != V.getValueType(); })) + // Shuffle inputs must be the same size as the result. + if (OpMask.size() != (unsigned)NumElts || + llvm::any_of(OpInputs, [VT](SDValue V) { + return VT.getSizeInBits() != V.getValueSizeInBits() || + !V.getValueType().isVector(); + })) return false; // Clear known elts that might have been set above. @@ -34709,10 +34731,14 @@ bool X86TargetLowering::SimplifyDemandedVectorEltsForTargetNode( } for (int Src = 0; Src != NumSrcs; ++Src) if (isSequentialOrUndefInRange(OpMask, 0, NumElts, Src * NumElts)) - return TLO.CombineTo(Op, OpInputs[Src]); + return TLO.CombineTo(Op, TLO.DAG.getBitcast(VT, OpInputs[Src])); // Attempt to simplify inputs. for (int Src = 0; Src != NumSrcs; ++Src) { + // TODO: Support inputs of different types. + if (OpInputs[Src].getValueType() != VT) + continue; + int Lo = Src * NumElts; APInt SrcElts = APInt::getNullValue(NumElts); for (int i = 0; i != NumElts; ++i) |