summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp56
1 files changed, 29 insertions, 27 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 660255612ee..f1be359862c 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -9097,6 +9097,28 @@ static SmallVector<int, 64> createTargetShuffleMask(ArrayRef<int> Mask,
return TargetMask;
}
+// Attempt to create a shuffle mask from a VSELECT condition mask.
+static bool createShuffleMaskFromVSELECT(SmallVectorImpl<int> &Mask,
+ SDValue Cond) {
+ if (!ISD::isBuildVectorOfConstantSDNodes(Cond.getNode()))
+ return false;
+
+ unsigned Size = Cond.getValueType().getVectorNumElements();
+ Mask.resize(Size, SM_SentinelUndef);
+
+ for (int i = 0; i != (int)Size; ++i) {
+ SDValue CondElt = Cond.getOperand(i);
+ Mask[i] = i;
+ // Arbitrarily choose from the 2nd operand if the select condition element
+ // is undef.
+ // TODO: Can we do better by matching patterns such as even/odd?
+ if (CondElt.isUndef() || isNullConstant(CondElt))
+ Mask[i] += Size;
+ }
+
+ return true;
+}
+
// Check if the shuffle mask is suitable for the AVX vpunpcklwd or vpunpckhwd
// instructions.
static bool isUnpackWdShuffleMask(ArrayRef<int> Mask, MVT VT) {
@@ -15135,26 +15157,15 @@ static SDValue lowerVSELECTtoVectorShuffle(SDValue Op,
SDValue Cond = Op.getOperand(0);
SDValue LHS = Op.getOperand(1);
SDValue RHS = Op.getOperand(2);
- SDLoc dl(Op);
MVT VT = Op.getSimpleValueType();
- if (!ISD::isBuildVectorOfConstantSDNodes(Cond.getNode()))
- return SDValue();
- auto *CondBV = cast<BuildVectorSDNode>(Cond);
-
// Only non-legal VSELECTs reach this lowering, convert those into generic
// shuffles and re-use the shuffle lowering path for blends.
SmallVector<int, 32> Mask;
- for (int i = 0, Size = VT.getVectorNumElements(); i < Size; ++i) {
- SDValue CondElt = CondBV->getOperand(i);
- int M = i;
- // We can't map undef to undef here. They have different meanings. Treat
- // as the same as zero.
- if (CondElt.isUndef() || isNullConstant(CondElt))
- M += Size;
- Mask.push_back(M);
- }
- return DAG.getVectorShuffle(VT, dl, LHS, RHS, Mask);
+ if (createShuffleMaskFromVSELECT(Mask, Cond))
+ return DAG.getVectorShuffle(VT, SDLoc(Op), LHS, RHS, Mask);
+
+ return SDValue();
}
SDValue X86TargetLowering::LowerVSELECT(SDValue Op, SelectionDAG &DAG) const {
@@ -32560,18 +32571,9 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
// Convert vselects with constant condition into shuffles.
if (ISD::isBuildVectorOfConstantSDNodes(Cond.getNode()) &&
DCI.isBeforeLegalizeOps()) {
- SmallVector<int, 64> Mask(VT.getVectorNumElements(), -1);
- for (int i = 0, Size = Mask.size(); i != Size; ++i) {
- SDValue CondElt = Cond->getOperand(i);
- Mask[i] = i;
- // Arbitrarily choose from the 2nd operand if the select condition element
- // is undef.
- // TODO: Can we do better by matching patterns such as even/odd?
- if (CondElt.isUndef() || isNullConstant(CondElt))
- Mask[i] += Size;
- }
-
- return DAG.getVectorShuffle(VT, DL, LHS, RHS, Mask);
+ SmallVector<int, 64> Mask;
+ if (createShuffleMaskFromVSELECT(Mask, Cond))
+ return DAG.getVectorShuffle(VT, DL, LHS, RHS, Mask);
}
// If we have SSE[12] support, try to form min/max nodes. SSE min/max
OpenPOWER on IntegriCloud