summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp202
1 files changed, 77 insertions, 125 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
index 8d6b73c5018..d6de85b3c83 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
@@ -127,12 +127,6 @@ class VectorLegalizer {
/// the remaining lanes, finally bitcasting to the proper type.
SDValue ExpandZERO_EXTEND_VECTOR_INREG(SDNode *Node);
- /// Implement expand-based legalization of ABS vector operations.
- /// If following expanding is legal/custom then do it:
- /// (ABS x) --> (XOR (ADD x, (SRA x, sizeof(x)-1)), (SRA x, sizeof(x)-1))
- /// else unroll the operation.
- SDValue ExpandABS(SDNode *Node);
-
/// Expand bswap of vectors into a shuffle if legal.
SDValue ExpandBSWAP(SDNode *Node);
@@ -143,19 +137,11 @@ class VectorLegalizer {
std::pair<SDValue, SDValue> ExpandLoad(SDNode *N);
SDValue ExpandStore(SDNode *N);
SDValue ExpandFNEG(SDNode *Node);
- SDValue ExpandFSUB(SDNode *Node);
- SDValue ExpandBITREVERSE(SDNode *Node);
- SDValue ExpandCTPOP(SDNode *Node);
- SDValue ExpandCTLZ(SDNode *Node);
- SDValue ExpandCTTZ(SDNode *Node);
- SDValue ExpandFunnelShift(SDNode *Node);
- SDValue ExpandROT(SDNode *Node);
- SDValue ExpandFMINNUM_FMAXNUM(SDNode *Node);
+ void ExpandFSUB(SDNode *Node, SmallVectorImpl<SDValue> &Results);
+ void ExpandBITREVERSE(SDNode *Node, SmallVectorImpl<SDValue> &Results);
void ExpandUADDSUBO(SDNode *Node, SmallVectorImpl<SDValue> &Results);
void ExpandSADDSUBO(SDNode *Node, SmallVectorImpl<SDValue> &Results);
void ExpandMULO(SDNode *Node, SmallVectorImpl<SDValue> &Results);
- SDValue ExpandAddSubSat(SDNode *Node);
- SDValue ExpandFixedPointMul(SDNode *Node);
SDValue ExpandFixedPointDiv(SDNode *Node);
SDValue ExpandStrictFPOp(SDNode *Node);
void ExpandStrictFPOp(SDNode *Node, SmallVectorImpl<SDValue> &Results);
@@ -846,6 +832,7 @@ SDValue VectorLegalizer::ExpandStore(SDNode *N) {
}
void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
+ SDValue Tmp;
switch (Node->getOpcode()) {
case ISD::SIGN_EXTEND_INREG:
Results.push_back(ExpandSEXTINREG(Node));
@@ -878,42 +865,61 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
Results.push_back(ExpandFNEG(Node));
return;
case ISD::FSUB:
- if (SDValue Tmp = ExpandFSUB(Node))
- Results.push_back(Tmp);
+ ExpandFSUB(Node, Results);
return;
case ISD::SETCC:
Results.push_back(UnrollVSETCC(Node));
return;
case ISD::ABS:
- Results.push_back(ExpandABS(Node));
- return;
- case ISD::BITREVERSE:
- if (SDValue Tmp = ExpandBITREVERSE(Node))
+ if (TLI.expandABS(Node, Tmp, DAG)) {
Results.push_back(Tmp);
+ return;
+ }
+ break;
+ case ISD::BITREVERSE:
+ ExpandBITREVERSE(Node, Results);
return;
case ISD::CTPOP:
- Results.push_back(ExpandCTPOP(Node));
- return;
+ if (TLI.expandCTPOP(Node, Tmp, DAG)) {
+ Results.push_back(Tmp);
+ return;
+ }
+ break;
case ISD::CTLZ:
case ISD::CTLZ_ZERO_UNDEF:
- Results.push_back(ExpandCTLZ(Node));
- return;
+ if (TLI.expandCTLZ(Node, Tmp, DAG)) {
+ Results.push_back(Tmp);
+ return;
+ }
+ break;
case ISD::CTTZ:
case ISD::CTTZ_ZERO_UNDEF:
- Results.push_back(ExpandCTTZ(Node));
- return;
+ if (TLI.expandCTTZ(Node, Tmp, DAG)) {
+ Results.push_back(Tmp);
+ return;
+ }
+ break;
case ISD::FSHL:
case ISD::FSHR:
- Results.push_back(ExpandFunnelShift(Node));
- return;
+ if (TLI.expandFunnelShift(Node, Tmp, DAG)) {
+ Results.push_back(Tmp);
+ return;
+ }
+ break;
case ISD::ROTL:
case ISD::ROTR:
- Results.push_back(ExpandROT(Node));
- return;
+ if (TLI.expandROT(Node, Tmp, DAG)) {
+ Results.push_back(Tmp);
+ return;
+ }
+ break;
case ISD::FMINNUM:
case ISD::FMAXNUM:
- Results.push_back(ExpandFMINNUM_FMAXNUM(Node));
- return;
+ if (SDValue Expanded = TLI.expandFMINNUM_FMAXNUM(Node, DAG)) {
+ Results.push_back(Expanded);
+ return;
+ }
+ break;
case ISD::UADDO:
case ISD::USUBO:
ExpandUADDSUBO(Node, Results);
@@ -930,20 +936,25 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
case ISD::SSUBSAT:
case ISD::UADDSAT:
case ISD::SADDSAT:
- Results.push_back(ExpandAddSubSat(Node));
- return;
+ if (SDValue Expanded = TLI.expandAddSubSat(Node, DAG)) {
+ Results.push_back(Expanded);
+ return;
+ }
+ break;
case ISD::SMULFIX:
case ISD::UMULFIX:
- Results.push_back(ExpandFixedPointMul(Node));
- return;
+ if (SDValue Expanded = TLI.expandFixedPointMul(Node, DAG)) {
+ Results.push_back(Expanded);
+ return;
+ }
+ break;
case ISD::SMULFIXSAT:
case ISD::UMULFIXSAT:
// FIXME: We do not expand SMULFIXSAT/UMULFIXSAT here yet, not sure exactly
// why. Maybe it results in worse codegen compared to the unroll for some
// targets? This should probably be investigated. And if we still prefer to
// unroll an explanation could be helpful.
- Results.push_back(DAG.UnrollVectorOp(Node));
- return;
+ break;
case ISD::SDIVFIX:
case ISD::UDIVFIX:
Results.push_back(ExpandFixedPointDiv(Node));
@@ -968,10 +979,9 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
case ISD::VECREDUCE_FMIN:
Results.push_back(TLI.expandVecReduce(Node, DAG));
return;
- default:
- Results.push_back(DAG.UnrollVectorOp(Node));
- return;
}
+
+ Results.push_back(DAG.UnrollVectorOp(Node));
}
SDValue VectorLegalizer::ExpandSELECT(SDNode *Node) {
@@ -1175,12 +1185,16 @@ SDValue VectorLegalizer::ExpandBSWAP(SDNode *Node) {
return DAG.getNode(ISD::BITCAST, DL, VT, Op);
}
-SDValue VectorLegalizer::ExpandBITREVERSE(SDNode *Node) {
+void VectorLegalizer::ExpandBITREVERSE(SDNode *Node,
+ SmallVectorImpl<SDValue> &Results) {
EVT VT = Node->getValueType(0);
// If we have the scalar operation, it's probably cheaper to unroll it.
- if (TLI.isOperationLegalOrCustom(ISD::BITREVERSE, VT.getScalarType()))
- return DAG.UnrollVectorOp(Node);
+ if (TLI.isOperationLegalOrCustom(ISD::BITREVERSE, VT.getScalarType())) {
+ SDValue Tmp = DAG.UnrollVectorOp(Node);
+ Results.push_back(Tmp);
+ return;
+ }
// If the vector element width is a whole number of bytes, test if its legal
// to BSWAP shuffle the bytes and then perform the BITREVERSE on the byte
@@ -1202,20 +1216,24 @@ SDValue VectorLegalizer::ExpandBITREVERSE(SDNode *Node) {
Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getUNDEF(ByteVT),
BSWAPMask);
Op = DAG.getNode(ISD::BITREVERSE, DL, ByteVT, Op);
- return DAG.getNode(ISD::BITCAST, DL, VT, Op);
+ Op = DAG.getNode(ISD::BITCAST, DL, VT, Op);
+ Results.push_back(Op);
+ return;
}
}
// If we have the appropriate vector bit operations, it is better to use them
// than unrolling and expanding each component.
- if (!TLI.isOperationLegalOrCustom(ISD::SHL, VT) ||
- !TLI.isOperationLegalOrCustom(ISD::SRL, VT) ||
- !TLI.isOperationLegalOrCustomOrPromote(ISD::AND, VT) ||
- !TLI.isOperationLegalOrCustomOrPromote(ISD::OR, VT))
- return DAG.UnrollVectorOp(Node);
+ if (TLI.isOperationLegalOrCustom(ISD::SHL, VT) &&
+ TLI.isOperationLegalOrCustom(ISD::SRL, VT) &&
+ TLI.isOperationLegalOrCustomOrPromote(ISD::AND, VT) &&
+ TLI.isOperationLegalOrCustomOrPromote(ISD::OR, VT))
+ // Let LegalizeDAG handle this later.
+ return;
- // Let LegalizeDAG handle this later.
- return SDValue();
+ // Otherwise unroll.
+ SDValue Tmp = DAG.UnrollVectorOp(Node);
+ Results.push_back(Tmp);
}
SDValue VectorLegalizer::ExpandVSELECT(SDNode *Node) {
@@ -1265,16 +1283,6 @@ SDValue VectorLegalizer::ExpandVSELECT(SDNode *Node) {
return DAG.getNode(ISD::BITCAST, DL, Node->getValueType(0), Val);
}
-SDValue VectorLegalizer::ExpandABS(SDNode *Node) {
- // Attempt to expand using TargetLowering.
- SDValue Result;
- if (TLI.expandABS(Node, Result, DAG))
- return Result;
-
- // Otherwise go ahead and unroll.
- return DAG.UnrollVectorOp(Node);
-}
-
void VectorLegalizer::ExpandFP_TO_UINT(SDNode *Node,
SmallVectorImpl<SDValue> &Results) {
// Attempt to expand using TargetLowering.
@@ -1394,62 +1402,18 @@ SDValue VectorLegalizer::ExpandFNEG(SDNode *Node) {
return DAG.UnrollVectorOp(Node);
}
-SDValue VectorLegalizer::ExpandFSUB(SDNode *Node) {
+void VectorLegalizer::ExpandFSUB(SDNode *Node,
+ SmallVectorImpl<SDValue> &Results) {
// For floating-point values, (a-b) is the same as a+(-b). If FNEG is legal,
// we can defer this to operation legalization where it will be lowered as
// a+(-b).
EVT VT = Node->getValueType(0);
if (TLI.isOperationLegalOrCustom(ISD::FNEG, VT) &&
TLI.isOperationLegalOrCustom(ISD::FADD, VT))
- return SDValue(); // Defer to LegalizeDAG
-
- return DAG.UnrollVectorOp(Node);
-}
+ return; // Defer to LegalizeDAG
-SDValue VectorLegalizer::ExpandCTPOP(SDNode *Node) {
- SDValue Result;
- if (TLI.expandCTPOP(Node, Result, DAG))
- return Result;
-
- return DAG.UnrollVectorOp(Node);
-}
-
-SDValue VectorLegalizer::ExpandCTLZ(SDNode *Node) {
- SDValue Result;
- if (TLI.expandCTLZ(Node, Result, DAG))
- return Result;
-
- return DAG.UnrollVectorOp(Node);
-}
-
-SDValue VectorLegalizer::ExpandCTTZ(SDNode *Node) {
- SDValue Result;
- if (TLI.expandCTTZ(Node, Result, DAG))
- return Result;
-
- return DAG.UnrollVectorOp(Node);
-}
-
-SDValue VectorLegalizer::ExpandFunnelShift(SDNode *Node) {
- SDValue Result;
- if (TLI.expandFunnelShift(Node, Result, DAG))
- return Result;
-
- return DAG.UnrollVectorOp(Node);
-}
-
-SDValue VectorLegalizer::ExpandROT(SDNode *Node) {
- SDValue Result;
- if (TLI.expandROT(Node, Result, DAG))
- return Result;
-
- return DAG.UnrollVectorOp(Node);
-}
-
-SDValue VectorLegalizer::ExpandFMINNUM_FMAXNUM(SDNode *Node) {
- if (SDValue Expanded = TLI.expandFMINNUM_FMAXNUM(Node, DAG))
- return Expanded;
- return DAG.UnrollVectorOp(Node);
+ SDValue Tmp = DAG.UnrollVectorOp(Node);
+ Results.push_back(Tmp);
}
void VectorLegalizer::ExpandUADDSUBO(SDNode *Node,
@@ -1478,18 +1442,6 @@ void VectorLegalizer::ExpandMULO(SDNode *Node,
Results.push_back(Overflow);
}
-SDValue VectorLegalizer::ExpandAddSubSat(SDNode *Node) {
- if (SDValue Expanded = TLI.expandAddSubSat(Node, DAG))
- return Expanded;
- return DAG.UnrollVectorOp(Node);
-}
-
-SDValue VectorLegalizer::ExpandFixedPointMul(SDNode *Node) {
- if (SDValue Expanded = TLI.expandFixedPointMul(Node, DAG))
- return Expanded;
- return DAG.UnrollVectorOp(Node);
-}
-
SDValue VectorLegalizer::ExpandFixedPointDiv(SDNode *Node) {
SDNode *N = Node;
if (SDValue Expanded = TLI.expandFixedPointDiv(N->getOpcode(), SDLoc(N),
OpenPOWER on IntegriCloud