forked from OSchip/llvm-project
Revert revert of r362112 with minor SystemZ test file corrections.
[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
This commit is contained in:
parent
a33964b570
commit
ac79007205
|
@ -857,6 +857,11 @@ private:
|
||||||
SDValue WidenVecOp_FCOPYSIGN(SDNode *N);
|
SDValue WidenVecOp_FCOPYSIGN(SDNode *N);
|
||||||
SDValue WidenVecOp_VECREDUCE(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
|
// Vector Widening Utilities Support: LegalizeVectorTypes.cpp
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
|
@ -1318,6 +1318,63 @@ void DAGTypeLegalizer::SplitVecRes_StrictFPOp(SDNode *N, SDValue &Lo,
|
||||||
ReplaceValueWith(SDValue(N, 1), Chain);
|
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,
|
void DAGTypeLegalizer::SplitVecRes_OverflowOp(SDNode *N, unsigned ResNo,
|
||||||
SDValue &Lo, SDValue &Hi) {
|
SDValue &Lo, SDValue &Hi) {
|
||||||
SDLoc dl(N);
|
SDLoc dl(N);
|
||||||
|
@ -2968,7 +3025,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_StrictFP(SDNode *N) {
|
||||||
|
|
||||||
// No legal vector version so unroll the vector operation and then widen.
|
// No legal vector version so unroll the vector operation and then widen.
|
||||||
if (NumElts == 1)
|
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.
|
// Since the operation can trap, apply operation on the original vector.
|
||||||
EVT MaxVT = VT;
|
EVT MaxVT = VT;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue