From 1e2e3ea584121f523aa4118f383927ed6b73246c Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Thu, 12 Sep 2013 19:04:12 +0000 Subject: [PATCH] Make the PPC fast-math sqrt expansion safe at 0 In fast-math mode sqrt(x) is calculated using the fast expansion of the reciprocal of the reciprocal sqrt expansion. The reciprocal and reciprocal sqrt expansions use the associated estimate instructions along with some Newton iterations. Unfortunately, as a result, sqrt(0) was being calculated as NaN, which is not correct. Now we explicitly return a result of zero if the input is zero. llvm-svn: 190624 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 22 ++++++++++++++++++++- llvm/test/CodeGen/PowerPC/recipest.ll | 5 ++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index d3410749d1a5..b4ba5274454e 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -7021,8 +7021,28 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, if (RV.getNode() != 0) { DCI.AddToWorklist(RV.getNode()); RV = DAGCombineFastRecip(RV, DCI); - if (RV.getNode() != 0) + if (RV.getNode() != 0) { + // Unfortunately, RV is now NaN if the input was exactly 0. Select out + // this case and force the answer to 0. + + EVT VT = RV.getValueType(); + + SDValue Zero = DAG.getConstantFP(0.0, VT.getScalarType()); + if (VT.isVector()) { + assert(VT.getVectorNumElements() == 4 && "Unknown vector type"); + Zero = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Zero, Zero, Zero, Zero); + } + + SDValue ZeroCmp = + DAG.getSetCC(dl, getSetCCResultType(*DAG.getContext(), VT), + N->getOperand(0), Zero, ISD::SETEQ); + DCI.AddToWorklist(ZeroCmp.getNode()); + DCI.AddToWorklist(RV.getNode()); + + RV = DAG.getNode(VT.isVector() ? ISD::VSELECT : ISD::SELECT, dl, VT, + ZeroCmp, Zero, RV); return RV; + } } } diff --git a/llvm/test/CodeGen/PowerPC/recipest.ll b/llvm/test/CodeGen/PowerPC/recipest.ll index 38d76820bb7b..891e801dd3b5 100644 --- a/llvm/test/CodeGen/PowerPC/recipest.ll +++ b/llvm/test/CodeGen/PowerPC/recipest.ll @@ -169,6 +169,7 @@ entry: ret double %r ; CHECK: @foo3 +; CHECK: fcmpu ; CHECK-DAG: frsqrte ; CHECK-DAG: fnmsub ; CHECK: fmul @@ -195,6 +196,7 @@ entry: ret float %r ; CHECK: @goo3 +; CHECK: fcmpu ; CHECK-DAG: frsqrtes ; CHECK-DAG: fnmsubs ; CHECK: fmuls @@ -217,7 +219,8 @@ entry: ; CHECK: @hoo3 ; CHECK: vrsqrtefp -; CHECK: vrefp +; CHECK-DAG: vrefp +; CHECK-DAG: vcmpeqfp ; CHECK-SAFE: @hoo3 ; CHECK-SAFE-NOT: vrsqrtefp