[X86][SSE] Pull out duplicate VSELECT to shuffle mask code. NFCI.

llvm-svn: 338693
This commit is contained in:
Simon Pilgrim 2018-08-02 09:20:27 +00:00
parent 48eba54f18
commit 8b16e15d47
1 changed files with 29 additions and 27 deletions

View File

@ -9097,6 +9097,28 @@ static SmallVector<int, 64> createTargetShuffleMask(ArrayRef<int> Mask,
return TargetMask; 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 // Check if the shuffle mask is suitable for the AVX vpunpcklwd or vpunpckhwd
// instructions. // instructions.
static bool isUnpackWdShuffleMask(ArrayRef<int> Mask, MVT VT) { static bool isUnpackWdShuffleMask(ArrayRef<int> Mask, MVT VT) {
@ -15135,26 +15157,15 @@ static SDValue lowerVSELECTtoVectorShuffle(SDValue Op,
SDValue Cond = Op.getOperand(0); SDValue Cond = Op.getOperand(0);
SDValue LHS = Op.getOperand(1); SDValue LHS = Op.getOperand(1);
SDValue RHS = Op.getOperand(2); SDValue RHS = Op.getOperand(2);
SDLoc dl(Op);
MVT VT = Op.getSimpleValueType(); 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 // Only non-legal VSELECTs reach this lowering, convert those into generic
// shuffles and re-use the shuffle lowering path for blends. // shuffles and re-use the shuffle lowering path for blends.
SmallVector<int, 32> Mask; SmallVector<int, 32> Mask;
for (int i = 0, Size = VT.getVectorNumElements(); i < Size; ++i) { if (createShuffleMaskFromVSELECT(Mask, Cond))
SDValue CondElt = CondBV->getOperand(i); return DAG.getVectorShuffle(VT, SDLoc(Op), LHS, RHS, Mask);
int M = i;
// We can't map undef to undef here. They have different meanings. Treat return SDValue();
// as the same as zero.
if (CondElt.isUndef() || isNullConstant(CondElt))
M += Size;
Mask.push_back(M);
}
return DAG.getVectorShuffle(VT, dl, LHS, RHS, Mask);
} }
SDValue X86TargetLowering::LowerVSELECT(SDValue Op, SelectionDAG &DAG) const { 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. // Convert vselects with constant condition into shuffles.
if (ISD::isBuildVectorOfConstantSDNodes(Cond.getNode()) && if (ISD::isBuildVectorOfConstantSDNodes(Cond.getNode()) &&
DCI.isBeforeLegalizeOps()) { DCI.isBeforeLegalizeOps()) {
SmallVector<int, 64> Mask(VT.getVectorNumElements(), -1); SmallVector<int, 64> Mask;
for (int i = 0, Size = Mask.size(); i != Size; ++i) { if (createShuffleMaskFromVSELECT(Mask, Cond))
SDValue CondElt = Cond->getOperand(i); return DAG.getVectorShuffle(VT, DL, LHS, RHS, Mask);
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);
} }
// If we have SSE[12] support, try to form min/max nodes. SSE min/max // If we have SSE[12] support, try to form min/max nodes. SSE min/max