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
This commit is contained in:
Hal Finkel 2013-04-04 22:44:12 +00:00
parent 0e58d92628
commit 7530a9f7d1
2 changed files with 75 additions and 0 deletions

View File

@ -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);

View File

@ -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)