mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-13 14:46:53 +00:00
fix PR9210 by implementing some type legalization logic for
vector fp conversions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125482 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
463b3c2a99
commit
593051b4e2
@ -587,6 +587,7 @@ private:
|
||||
SDValue SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N);
|
||||
SDValue SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo);
|
||||
SDValue SplitVecOp_CONCAT_VECTORS(SDNode *N);
|
||||
SDValue SplitVecOp_FP_ROUND(SDNode *N);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Vector Widening Support: LegalizeVectorTypes.cpp
|
||||
|
@ -981,6 +981,7 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {
|
||||
case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break;
|
||||
case ISD::EXTRACT_VECTOR_ELT:Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break;
|
||||
case ISD::CONCAT_VECTORS: Res = SplitVecOp_CONCAT_VECTORS(N); break;
|
||||
case ISD::FP_ROUND: Res = SplitVecOp_FP_ROUND(N); break;
|
||||
case ISD::STORE:
|
||||
Res = SplitVecOp_STORE(cast<StoreSDNode>(N), OpNo);
|
||||
break;
|
||||
@ -992,6 +993,8 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {
|
||||
case ISD::FP_TO_UINT:
|
||||
case ISD::SINT_TO_FP:
|
||||
case ISD::UINT_TO_FP:
|
||||
case ISD::FP_EXTEND:
|
||||
case ISD::FTRUNC:
|
||||
case ISD::TRUNCATE:
|
||||
case ISD::SIGN_EXTEND:
|
||||
case ISD::ZERO_EXTEND:
|
||||
@ -1171,6 +1174,24 @@ SDValue DAGTypeLegalizer::SplitVecOp_CONCAT_VECTORS(SDNode *N) {
|
||||
&Elts[0], Elts.size());
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SplitVecOp_FP_ROUND(SDNode *N) {
|
||||
// The result has a legal vector type, but the input needs splitting.
|
||||
EVT ResVT = N->getValueType(0);
|
||||
SDValue Lo, Hi;
|
||||
DebugLoc DL = N->getDebugLoc();
|
||||
GetSplitVector(N->getOperand(0), Lo, Hi);
|
||||
EVT InVT = Lo.getValueType();
|
||||
|
||||
EVT OutVT = EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(),
|
||||
InVT.getVectorNumElements());
|
||||
|
||||
Lo = DAG.getNode(ISD::FP_ROUND, DL, OutVT, Lo, N->getOperand(1));
|
||||
Hi = DAG.getNode(ISD::FP_ROUND, DL, OutVT, Hi, N->getOperand(1));
|
||||
|
||||
return DAG.getNode(ISD::CONCAT_VECTORS, DL, ResVT, Lo, Hi);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Result Vector Widening
|
||||
@ -1422,7 +1443,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) {
|
||||
|
||||
SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
|
||||
SDValue InOp = N->getOperand(0);
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
DebugLoc DL = N->getDebugLoc();
|
||||
|
||||
EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
||||
unsigned WidenNumElts = WidenVT.getVectorNumElements();
|
||||
@ -1438,8 +1459,11 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
|
||||
InOp = GetWidenedVector(N->getOperand(0));
|
||||
InVT = InOp.getValueType();
|
||||
InVTNumElts = InVT.getVectorNumElements();
|
||||
if (InVTNumElts == WidenNumElts)
|
||||
return DAG.getNode(Opcode, dl, WidenVT, InOp);
|
||||
if (InVTNumElts == WidenNumElts) {
|
||||
if (N->getNumOperands() == 1)
|
||||
return DAG.getNode(Opcode, DL, WidenVT, InOp);
|
||||
return DAG.getNode(Opcode, DL, WidenVT, InOp, N->getOperand(1));
|
||||
}
|
||||
}
|
||||
|
||||
if (TLI.isTypeLegal(InWidenVT)) {
|
||||
@ -1456,16 +1480,20 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
|
||||
SDValue UndefVal = DAG.getUNDEF(InVT);
|
||||
for (unsigned i = 1; i != NumConcat; ++i)
|
||||
Ops[i] = UndefVal;
|
||||
return DAG.getNode(Opcode, dl, WidenVT,
|
||||
DAG.getNode(ISD::CONCAT_VECTORS, dl, InWidenVT,
|
||||
&Ops[0], NumConcat));
|
||||
SDValue InVec = DAG.getNode(ISD::CONCAT_VECTORS, DL, InWidenVT,
|
||||
&Ops[0], NumConcat);
|
||||
if (N->getNumOperands() == 1)
|
||||
return DAG.getNode(Opcode, DL, WidenVT, InVec);
|
||||
return DAG.getNode(Opcode, DL, WidenVT, InVec, N->getOperand(1));
|
||||
}
|
||||
|
||||
if (InVTNumElts % WidenNumElts == 0) {
|
||||
SDValue InVal = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, InWidenVT,
|
||||
InOp, DAG.getIntPtrConstant(0));
|
||||
// Extract the input and convert the shorten input vector.
|
||||
return DAG.getNode(Opcode, dl, WidenVT,
|
||||
DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InWidenVT,
|
||||
InOp, DAG.getIntPtrConstant(0)));
|
||||
if (N->getNumOperands() == 1)
|
||||
return DAG.getNode(Opcode, DL, WidenVT, InVal);
|
||||
return DAG.getNode(Opcode, DL, WidenVT, InVal, N->getOperand(1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1474,16 +1502,20 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
|
||||
EVT EltVT = WidenVT.getVectorElementType();
|
||||
unsigned MinElts = std::min(InVTNumElts, WidenNumElts);
|
||||
unsigned i;
|
||||
for (i=0; i < MinElts; ++i)
|
||||
Ops[i] = DAG.getNode(Opcode, dl, EltVT,
|
||||
DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp,
|
||||
DAG.getIntPtrConstant(i)));
|
||||
for (i=0; i < MinElts; ++i) {
|
||||
SDValue Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, InEltVT, InOp,
|
||||
DAG.getIntPtrConstant(i));
|
||||
if (N->getNumOperands() == 1)
|
||||
Ops[i] = DAG.getNode(Opcode, DL, EltVT, Val);
|
||||
else
|
||||
Ops[i] = DAG.getNode(Opcode, DL, EltVT, Val, N->getOperand(1));
|
||||
}
|
||||
|
||||
SDValue UndefVal = DAG.getUNDEF(EltVT);
|
||||
for (; i < WidenNumElts; ++i)
|
||||
Ops[i] = UndefVal;
|
||||
|
||||
return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts);
|
||||
return DAG.getNode(ISD::BUILD_VECTOR, DL, WidenVT, &Ops[0], WidenNumElts);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::WidenVecRes_POWI(SDNode *N) {
|
||||
|
@ -214,3 +214,11 @@ entry:
|
||||
store <4 x float> %2, <4 x float> * undef
|
||||
ret void
|
||||
}
|
||||
|
||||
; PR9210
|
||||
define <4 x float> @f(<4 x double>) nounwind {
|
||||
entry:
|
||||
%double2float.i = fptrunc <4 x double> %0 to <4 x float>
|
||||
ret <4 x float> %double2float.i
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user