Skip to content

Commit

Permalink
Revert revert of r362112 with minor SystemZ test file corrections.
Browse files Browse the repository at this point in the history
[FPEnv] Added a special UnrollVectorOp method to deal with the chain on StrictFP opcodes

This change creates UnrollVectorOp_StrictFP. The purpose of this is to address a failure that consistently occurs when calling StrictFP functions on vectors whose number of elements is 3 + 2n on most platforms, such as PowerPC or SystemZ. The old UnrollVectorOp method does not expect that the vector that it will unroll will have a chain, so it has an assert that prevents it from running if this is the case. This new StrictFP version of the method deals with the chain while unrolling the vector. With this new function in place during vector widending, llc can run vector-constrained-fp-intrinsics.ll for SystemZ successfully.

Submitted by:	Drew Wock <drew.wock@sas.com>
Reviewed by:	Cameron McInally, Kevin P. Neal
Approved by:	Cameron McInally
Differential Revision:	https://reviews.llvm.org/D62546

llvm-svn: 362241
  • Loading branch information
kpneal committed May 31, 2019
1 parent a33964b commit ac79007
Show file tree
Hide file tree
Showing 3 changed files with 6,512 additions and 1 deletion.
5 changes: 5 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
Expand Up @@ -857,6 +857,11 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
SDValue WidenVecOp_FCOPYSIGN(SDNode *N);
SDValue WidenVecOp_VECREDUCE(SDNode *N);

/// Helper function to generate a set of operations to perform
/// a vector operation for a wider type.
///
SDValue UnrollVectorOp_StrictFP(SDNode *N, unsigned ResNE);

//===--------------------------------------------------------------------===//
// Vector Widening Utilities Support: LegalizeVectorTypes.cpp
//===--------------------------------------------------------------------===//
Expand Down
59 changes: 58 additions & 1 deletion llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
Expand Up @@ -1318,6 +1318,63 @@ void DAGTypeLegalizer::SplitVecRes_StrictFPOp(SDNode *N, SDValue &Lo,
ReplaceValueWith(SDValue(N, 1), Chain);
}

SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(SDNode *N, unsigned ResNE) {
SDValue Chain = N->getOperand(0);
EVT VT = N->getValueType(0);
unsigned NE = VT.getVectorNumElements();
EVT EltVT = VT.getVectorElementType();
SDLoc dl(N);

SmallVector<SDValue, 8> Scalars;
SmallVector<SDValue, 4> Operands(N->getNumOperands());

// If ResNE is 0, fully unroll the vector op.
if (ResNE == 0)
ResNE = NE;
else if (NE > ResNE)
NE = ResNE;

//The results of each unrolled operation, including the chain.
EVT ChainVTs[] = {EltVT, MVT::Other};
SmallVector<SDValue, 8> Chains;

unsigned i;
for (i = 0; i != NE; ++i) {
Operands[0] = Chain;
for (unsigned j = 1, e = N->getNumOperands(); j != e; ++j) {
SDValue Operand = N->getOperand(j);
EVT OperandVT = Operand.getValueType();
if (OperandVT.isVector()) {
EVT OperandEltVT = OperandVT.getVectorElementType();
Operands[j] =
DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, OperandEltVT, Operand,
DAG.getConstant(i, dl, TLI.getVectorIdxTy(
DAG.getDataLayout())));
} else {
Operands[j] = Operand;
}
}
SDValue Scalar = DAG.getNode(N->getOpcode(), dl, ChainVTs, Operands);
Scalar.getNode()->setFlags(N->getFlags());

//Add in the scalar as well as its chain value to the
//result vectors.
Scalars.push_back(Scalar);
Chains.push_back(Scalar.getValue(1));
}

for (; i < ResNE; ++i)
Scalars.push_back(DAG.getUNDEF(EltVT));

// Build a new factor node to connect the chain back together.
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chains);
ReplaceValueWith(SDValue(N, 1), Chain);

// Create a new BUILD_VECTOR node
EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, ResNE);
return DAG.getBuildVector(VecVT, dl, Scalars);
}

void DAGTypeLegalizer::SplitVecRes_OverflowOp(SDNode *N, unsigned ResNo,
SDValue &Lo, SDValue &Hi) {
SDLoc dl(N);
Expand Down Expand Up @@ -2968,7 +3025,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_StrictFP(SDNode *N) {

// No legal vector version so unroll the vector operation and then widen.
if (NumElts == 1)
return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements());
return UnrollVectorOp_StrictFP(N, WidenVT.getVectorNumElements());

// Since the operation can trap, apply operation on the original vector.
EVT MaxVT = VT;
Expand Down

0 comments on commit ac79007

Please sign in to comment.