diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index d3410749d1a..b4ba5274454 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/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/test/CodeGen/PowerPC/recipest.ll b/test/CodeGen/PowerPC/recipest.ll index 38d76820bb7..891e801dd3b 100644 --- a/test/CodeGen/PowerPC/recipest.ll +++ b/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