summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp78
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)
OpenPOWER on IntegriCloud