From 7530a9f7d1e62b28e04d771158613c2954cc8d8c Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Thu, 4 Apr 2013 22:44:12 +0000 Subject: [PATCH] PPC: Improve code generation for mixed-precision reciprocal sqrt The DAGCombine logic that recognized a/sqrt(b) and transformed it into a multiplication by the reciprocal sqrt did not handle cases where the sqrt and the division were separated by an fpext or fptrunc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178801 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCISelLowering.cpp | 27 +++++++++++++++ test/CodeGen/PowerPC/recipest.ll | 48 ++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index e33d2cc7165..8195f5eb050 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -6849,6 +6849,33 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, return DAG.getNode(ISD::FMUL, dl, N->getValueType(0), N->getOperand(0), RV); } + } else if (N->getOperand(1).getOpcode() == ISD::FP_EXTEND && + N->getOperand(1).getOperand(0).getOpcode() == ISD::FSQRT) { + SDValue RV = + DAGCombineFastRecipFSQRT(N->getOperand(1).getOperand(0).getOperand(0), + DCI); + if (RV.getNode() != 0) { + DCI.AddToWorklist(RV.getNode()); + RV = DAG.getNode(ISD::FP_EXTEND, N->getOperand(1).getDebugLoc(), + N->getValueType(0), RV); + DCI.AddToWorklist(RV.getNode()); + return DAG.getNode(ISD::FMUL, dl, N->getValueType(0), + N->getOperand(0), RV); + } + } else if (N->getOperand(1).getOpcode() == ISD::FP_ROUND && + N->getOperand(1).getOperand(0).getOpcode() == ISD::FSQRT) { + SDValue RV = + DAGCombineFastRecipFSQRT(N->getOperand(1).getOperand(0).getOperand(0), + DCI); + if (RV.getNode() != 0) { + DCI.AddToWorklist(RV.getNode()); + RV = DAG.getNode(ISD::FP_ROUND, N->getOperand(1).getDebugLoc(), + N->getValueType(0), RV, + N->getOperand(1).getOperand(1)); + DCI.AddToWorklist(RV.getNode()); + return DAG.getNode(ISD::FMUL, dl, N->getValueType(0), + N->getOperand(0), RV); + } } SDValue RV = DAGCombineFastRecip(N->getOperand(1), DCI); diff --git a/test/CodeGen/PowerPC/recipest.ll b/test/CodeGen/PowerPC/recipest.ll index cad98c5a352..89705faa46e 100644 --- a/test/CodeGen/PowerPC/recipest.ll +++ b/test/CodeGen/PowerPC/recipest.ll @@ -31,6 +31,54 @@ entry: ; CHECK-SAFE: blr } +define double @foof(double %a, float %b) nounwind { +entry: + %x = call float @llvm.sqrt.f32(float %b) + %y = fpext float %x to double + %r = fdiv double %a, %y + ret double %r + +; CHECK: @foof +; CHECK: frsqrtes +; CHECK: fnmsubs +; CHECK: fmuls +; CHECK: fmadds +; CHECK: fmuls +; CHECK: fmul +; CHECK: blr + +; CHECK-SAFE: @foof +; CHECK-SAFE: fsqrts +; CHECK-SAFE: fdiv +; CHECK-SAFE: blr +} + +define float @food(float %a, double %b) nounwind { +entry: + %x = call double @llvm.sqrt.f64(double %b) + %y = fptrunc double %x to float + %r = fdiv float %a, %y + ret float %r + +; CHECK: @foo +; CHECK: frsqrte +; CHECK: fnmsub +; CHECK: fmul +; CHECK: fmadd +; CHECK: fmul +; CHECK: fmul +; CHECK: fmadd +; CHECK: fmul +; CHECK: frsp +; CHECK: fmuls +; CHECK: blr + +; CHECK-SAFE: @foo +; CHECK-SAFE: fsqrt +; CHECK-SAFE: fdivs +; CHECK-SAFE: blr +} + define float @goo(float %a, float %b) nounwind { entry: %x = call float @llvm.sqrt.f32(float %b)