forked from OSchip/llvm-project
[TargetLowering] Move LegalizeDAG FP_TO_UINT handling to TargetLowering::expandFP_TO_UINT. NFCI.
First step towards fixing PR17686 and adding vector support. llvm-svn: 345452
This commit is contained in:
parent
88116e905e
commit
3cf33fcdd6
|
@ -3663,6 +3663,12 @@ public:
|
|||
/// \returns True, if the expansion was successful, false otherwise
|
||||
bool expandFP_TO_SINT(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
|
||||
|
||||
/// Expand float to UINT conversion
|
||||
/// \param N Node to expand
|
||||
/// \param Result output after conversion
|
||||
/// \returns True, if the expansion was successful, false otherwise
|
||||
bool expandFP_TO_UINT(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
|
||||
|
||||
/// Expand UINT(i64) to double(f64) conversion
|
||||
/// \param N Node to expand
|
||||
/// \param Result output after conversion
|
||||
|
|
|
@ -2877,29 +2877,10 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
|
|||
if (TLI.expandFP_TO_SINT(Node, Tmp1, DAG))
|
||||
Results.push_back(Tmp1);
|
||||
break;
|
||||
case ISD::FP_TO_UINT: {
|
||||
SDValue True, False;
|
||||
EVT VT = Node->getOperand(0).getValueType();
|
||||
EVT NVT = Node->getValueType(0);
|
||||
APFloat apf(DAG.EVTToAPFloatSemantics(VT),
|
||||
APInt::getNullValue(VT.getSizeInBits()));
|
||||
APInt x = APInt::getSignMask(NVT.getSizeInBits());
|
||||
(void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven);
|
||||
Tmp1 = DAG.getConstantFP(apf, dl, VT);
|
||||
Tmp2 = DAG.getSetCC(dl, getSetCCResultType(VT),
|
||||
Node->getOperand(0),
|
||||
Tmp1, ISD::SETLT);
|
||||
True = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Node->getOperand(0));
|
||||
// TODO: Should any fast-math-flags be set for the FSUB?
|
||||
False = DAG.getNode(ISD::FP_TO_SINT, dl, NVT,
|
||||
DAG.getNode(ISD::FSUB, dl, VT,
|
||||
Node->getOperand(0), Tmp1));
|
||||
False = DAG.getNode(ISD::XOR, dl, NVT, False,
|
||||
DAG.getConstant(x, dl, NVT));
|
||||
Tmp1 = DAG.getSelect(dl, NVT, Tmp2, True, False);
|
||||
Results.push_back(Tmp1);
|
||||
case ISD::FP_TO_UINT:
|
||||
if (TLI.expandFP_TO_UINT(Node, Tmp1, DAG))
|
||||
Results.push_back(Tmp1);
|
||||
break;
|
||||
}
|
||||
case ISD::VAARG:
|
||||
Results.push_back(DAG.expandVAArg(Node));
|
||||
Results.push_back(Results[0].getValue(1));
|
||||
|
|
|
@ -4137,6 +4137,37 @@ bool TargetLowering::expandFP_TO_SINT(SDNode *Node, SDValue &Result,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TargetLowering::expandFP_TO_UINT(SDNode *Node, SDValue &Result,
|
||||
SelectionDAG &DAG) const {
|
||||
SDLoc dl(SDValue(Node, 0));
|
||||
SDValue Src = Node->getOperand(0);
|
||||
|
||||
EVT SrcVT = Src.getValueType();
|
||||
EVT DstVT = Node->getValueType(0);
|
||||
EVT SetCCVT =
|
||||
getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), SrcVT);
|
||||
|
||||
// Expand based on maximum range of FP_TO_SINT:
|
||||
// True = fp_to_sint(Src)
|
||||
// False = 0x8000000000000000 + fp_to_sint(Src - 0x8000000000000000)
|
||||
// Result = select (Src < 0x8000000000000000), True, False
|
||||
APFloat apf(DAG.EVTToAPFloatSemantics(SrcVT),
|
||||
APInt::getNullValue(SrcVT.getScalarSizeInBits()));
|
||||
APInt x = APInt::getSignMask(DstVT.getScalarSizeInBits());
|
||||
(void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven);
|
||||
|
||||
SDValue Tmp1 = DAG.getConstantFP(apf, dl, SrcVT);
|
||||
SDValue Tmp2 = DAG.getSetCC(dl, SetCCVT, Src, Tmp1, ISD::SETLT);
|
||||
SDValue True = DAG.getNode(ISD::FP_TO_SINT, dl, DstVT, Src);
|
||||
// TODO: Should any fast-math-flags be set for the FSUB?
|
||||
SDValue False = DAG.getNode(ISD::FP_TO_SINT, dl, DstVT,
|
||||
DAG.getNode(ISD::FSUB, dl, SrcVT, Src, Tmp1));
|
||||
False =
|
||||
DAG.getNode(ISD::XOR, dl, DstVT, False, DAG.getConstant(x, dl, DstVT));
|
||||
Result = DAG.getSelect(dl, DstVT, Tmp2, True, False);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TargetLowering::expandUINT_TO_FP(SDNode *Node, SDValue &Result,
|
||||
SelectionDAG &DAG) const {
|
||||
SDValue Src = Node->getOperand(0);
|
||||
|
|
Loading…
Reference in New Issue