@@ -18869,20 +18869,45 @@ static SDValue foldFPToIntToFP(SDNode *N, const SDLoc &DL, SelectionDAG &DAG,
1886918869 // FIXME: We should be able to use node-level FMF here.
1887018870 // TODO: If strict math, should we use FABS (+ range check for signed cast)?
1887118871 EVT VT = N->getValueType(0);
18872- if (!TLI.isOperationLegal(ISD::FTRUNC, VT) ||
18873- !DAG.getTarget().Options.NoSignedZerosFPMath)
18872+ if (!TLI.isOperationLegal(ISD::FTRUNC, VT))
1887418873 return SDValue();
1887518874
1887618875 // fptosi/fptoui round towards zero, so converting from FP to integer and
1887718876 // back is the same as an 'ftrunc': [us]itofp (fpto[us]i X) --> ftrunc X
1887818877 SDValue N0 = N->getOperand(0);
1887918878 if (N->getOpcode() == ISD::SINT_TO_FP && N0.getOpcode() == ISD::FP_TO_SINT &&
18880- N0.getOperand(0).getValueType() == VT)
18881- return DAG.getNode(ISD::FTRUNC, DL, VT, N0.getOperand(0));
18879+ N0.getOperand(0).getValueType() == VT) {
18880+ if (DAG.getTarget().Options.NoSignedZerosFPMath)
18881+ return DAG.getNode(ISD::FTRUNC, DL, VT, N0.getOperand(0));
18882+
18883+ unsigned IntWidth = N0.getValueSizeInBits();
18884+ APInt APMax = APInt::getSignedMaxValue(IntWidth);
18885+ APInt APMin = APInt::getSignedMinValue(IntWidth);
18886+
18887+ APFloat MaxAPF(VT.getFltSemantics());
18888+ MaxAPF.convertFromAPInt(APMax, true, APFloat::rmTowardZero);
18889+ APFloat MinAPF(VT.getFltSemantics());
18890+ MinAPF.convertFromAPInt(APMin, true, APFloat::rmTowardZero);
18891+
18892+ SDValue MaxFP = DAG.getConstantFP(MaxAPF, DL, VT);
18893+ SDValue MinFP = DAG.getConstantFP(MinAPF, DL, VT);
18894+
18895+ SDValue Clamped = DAG.getNode(ISD::FMINNUM, DL, VT,
18896+ DAG.getNode(ISD::FMAXNUM, DL, VT, N0->getOperand(0), MinFP),
18897+ MaxFP);
18898+ return DAG.getNode(ISD::FTRUNC, DL, VT, Clamped);
18899+ }
1888218900
1888318901 if (N->getOpcode() == ISD::UINT_TO_FP && N0.getOpcode() == ISD::FP_TO_UINT &&
18884- N0.getOperand(0).getValueType() == VT)
18885- return DAG.getNode(ISD::FTRUNC, DL, VT, N0.getOperand(0));
18902+ N0.getOperand(0).getValueType() == VT) {
18903+ if (DAG.getTarget().Options.NoSignedZerosFPMath)
18904+ return DAG.getNode(ISD::FTRUNC, DL, VT, N0.getOperand(0));
18905+
18906+ if (TLI.isFAbsFree(VT)) {
18907+ SDValue Abs = DAG.getNode(ISD::FABS, DL, VT, N0.getOperand(0));
18908+ return DAG.getNode(ISD::FTRUNC, DL, VT, Abs);
18909+ }
18910+ }
1888618911
1888718912 return SDValue();
1888818913}
0 commit comments