Skip to content

Commit 2e18076

Browse files
committed
[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: http://reviews.llvm.org/D62546 llvm-svn: 362112
1 parent 7c75ac0 commit 2e18076

File tree

3 files changed

+6508
-1
lines changed

3 files changed

+6508
-1
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,11 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
857857
SDValue WidenVecOp_FCOPYSIGN(SDNode *N);
858858
SDValue WidenVecOp_VECREDUCE(SDNode *N);
859859

860+
/// Helper function to generate a set of operations to perform
861+
/// a vector operation for a wider type.
862+
///
863+
SDValue UnrollVectorOp_StrictFP(SDNode *N, unsigned ResNE);
864+
860865
//===--------------------------------------------------------------------===//
861866
// Vector Widening Utilities Support: LegalizeVectorTypes.cpp
862867
//===--------------------------------------------------------------------===//

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1318,6 +1318,63 @@ void DAGTypeLegalizer::SplitVecRes_StrictFPOp(SDNode *N, SDValue &Lo,
13181318
ReplaceValueWith(SDValue(N, 1), Chain);
13191319
}
13201320

1321+
SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(SDNode *N, unsigned ResNE) {
1322+
SDValue Chain = N->getOperand(0);
1323+
EVT VT = N->getValueType(0);
1324+
unsigned NE = VT.getVectorNumElements();
1325+
EVT EltVT = VT.getVectorElementType();
1326+
SDLoc dl(N);
1327+
1328+
SmallVector<SDValue, 8> Scalars;
1329+
SmallVector<SDValue, 4> Operands(N->getNumOperands());
1330+
1331+
// If ResNE is 0, fully unroll the vector op.
1332+
if (ResNE == 0)
1333+
ResNE = NE;
1334+
else if (NE > ResNE)
1335+
NE = ResNE;
1336+
1337+
//The results of each unrolled operation, including the chain.
1338+
EVT ChainVTs[] = {EltVT, MVT::Other};
1339+
SmallVector<SDValue, 8> Chains;
1340+
1341+
unsigned i;
1342+
for (i = 0; i != NE; ++i) {
1343+
Operands[0] = Chain;
1344+
for (unsigned j = 1, e = N->getNumOperands(); j != e; ++j) {
1345+
SDValue Operand = N->getOperand(j);
1346+
EVT OperandVT = Operand.getValueType();
1347+
if (OperandVT.isVector()) {
1348+
EVT OperandEltVT = OperandVT.getVectorElementType();
1349+
Operands[j] =
1350+
DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, OperandEltVT, Operand,
1351+
DAG.getConstant(i, dl, TLI.getVectorIdxTy(
1352+
DAG.getDataLayout())));
1353+
} else {
1354+
Operands[j] = Operand;
1355+
}
1356+
}
1357+
SDValue Scalar = DAG.getNode(N->getOpcode(), dl, ChainVTs, Operands);
1358+
Scalar.getNode()->setFlags(N->getFlags());
1359+
1360+
//Add in the scalar as well as its chain value to the
1361+
//result vectors.
1362+
Scalars.push_back(Scalar);
1363+
Chains.push_back(Scalar.getValue(1));
1364+
}
1365+
1366+
for (; i < ResNE; ++i)
1367+
Scalars.push_back(DAG.getUNDEF(EltVT));
1368+
1369+
// Build a new factor node to connect the chain back together.
1370+
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chains);
1371+
ReplaceValueWith(SDValue(N, 1), Chain);
1372+
1373+
// Create a new BUILD_VECTOR node
1374+
EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, ResNE);
1375+
return DAG.getBuildVector(VecVT, dl, Scalars);
1376+
}
1377+
13211378
void DAGTypeLegalizer::SplitVecRes_OverflowOp(SDNode *N, unsigned ResNo,
13221379
SDValue &Lo, SDValue &Hi) {
13231380
SDLoc dl(N);
@@ -2968,7 +3025,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_StrictFP(SDNode *N) {
29683025

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

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

0 commit comments

Comments
 (0)