Skip to content

Commit 51bf419

Browse files
committed
[DAGCombiner] Extend FP-to-Int cast without requiring nsz
1 parent 8553bd2 commit 51bf419

File tree

1 file changed

+31
-6
lines changed

1 file changed

+31
-6
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)