mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
Use the target-specified iteration count to opt out of any further refinement of an estimate. NFC.
llvm-svn: 218700
This commit is contained in:
parent
c095454ca2
commit
abcb3acee5
@ -11778,35 +11778,36 @@ SDValue DAGCombiner::BuildReciprocalEstimate(SDValue Op) {
|
||||
// Expose the DAG combiner to the target combiner implementations.
|
||||
TargetLowering::DAGCombinerInfo DCI(DAG, Level, false, this);
|
||||
|
||||
unsigned Iterations;
|
||||
unsigned Iterations = 0;
|
||||
if (SDValue Est = TLI.getRecipEstimate(Op, DCI, Iterations)) {
|
||||
// Newton iteration for a function: F(X) is X_{i+1} = X_i - F(X_i)/F'(X_i)
|
||||
// For the reciprocal, we need to find the zero of the function:
|
||||
// F(X) = A X - 1 [which has a zero at X = 1/A]
|
||||
// =>
|
||||
// X_{i+1} = X_i (2 - A X_i) = X_i + X_i (1 - A X_i) [this second form
|
||||
// does not require additional intermediate precision]
|
||||
EVT VT = Op.getValueType();
|
||||
SDLoc DL(Op);
|
||||
SDValue FPOne = DAG.getConstantFP(1.0, VT);
|
||||
if (Iterations) {
|
||||
// Newton iteration for a function: F(X) is X_{i+1} = X_i - F(X_i)/F'(X_i)
|
||||
// For the reciprocal, we need to find the zero of the function:
|
||||
// F(X) = A X - 1 [which has a zero at X = 1/A]
|
||||
// =>
|
||||
// X_{i+1} = X_i (2 - A X_i) = X_i + X_i (1 - A X_i) [this second form
|
||||
// does not require additional intermediate precision]
|
||||
EVT VT = Op.getValueType();
|
||||
SDLoc DL(Op);
|
||||
SDValue FPOne = DAG.getConstantFP(1.0, VT);
|
||||
|
||||
AddToWorklist(Est.getNode());
|
||||
|
||||
// Newton iterations: Est = Est + Est (1 - Arg * Est)
|
||||
for (unsigned i = 0; i < Iterations; ++i) {
|
||||
SDValue NewEst = DAG.getNode(ISD::FMUL, DL, VT, Op, Est);
|
||||
AddToWorklist(NewEst.getNode());
|
||||
|
||||
NewEst = DAG.getNode(ISD::FSUB, DL, VT, FPOne, NewEst);
|
||||
AddToWorklist(NewEst.getNode());
|
||||
|
||||
NewEst = DAG.getNode(ISD::FMUL, DL, VT, Est, NewEst);
|
||||
AddToWorklist(NewEst.getNode());
|
||||
|
||||
Est = DAG.getNode(ISD::FADD, DL, VT, Est, NewEst);
|
||||
AddToWorklist(Est.getNode());
|
||||
}
|
||||
|
||||
// Newton iterations: Est = Est + Est (1 - Arg * Est)
|
||||
for (unsigned i = 0; i < Iterations; ++i) {
|
||||
SDValue NewEst = DAG.getNode(ISD::FMUL, DL, VT, Op, Est);
|
||||
AddToWorklist(NewEst.getNode());
|
||||
|
||||
NewEst = DAG.getNode(ISD::FSUB, DL, VT, FPOne, NewEst);
|
||||
AddToWorklist(NewEst.getNode());
|
||||
|
||||
NewEst = DAG.getNode(ISD::FMUL, DL, VT, Est, NewEst);
|
||||
AddToWorklist(NewEst.getNode());
|
||||
|
||||
Est = DAG.getNode(ISD::FADD, DL, VT, Est, NewEst);
|
||||
AddToWorklist(Est.getNode());
|
||||
}
|
||||
}
|
||||
return Est;
|
||||
}
|
||||
|
||||
@ -11819,43 +11820,44 @@ SDValue DAGCombiner::BuildRsqrtEstimate(SDValue Op) {
|
||||
|
||||
// Expose the DAG combiner to the target combiner implementations.
|
||||
TargetLowering::DAGCombinerInfo DCI(DAG, Level, false, this);
|
||||
unsigned Iterations;
|
||||
unsigned Iterations = 0;
|
||||
if (SDValue Est = TLI.getRsqrtEstimate(Op, DCI, Iterations)) {
|
||||
// Newton iteration for a function: F(X) is X_{i+1} = X_i - F(X_i)/F'(X_i)
|
||||
// For the reciprocal sqrt, we need to find the zero of the function:
|
||||
// F(X) = 1/X^2 - A [which has a zero at X = 1/sqrt(A)]
|
||||
// =>
|
||||
// X_{i+1} = X_i (1.5 - A X_i^2 / 2)
|
||||
// As a result, we precompute A/2 prior to the iteration loop.
|
||||
EVT VT = Op.getValueType();
|
||||
SDLoc DL(Op);
|
||||
SDValue FPThreeHalves = DAG.getConstantFP(1.5, VT);
|
||||
if (Iterations) {
|
||||
// Newton iteration for a function: F(X) is X_{i+1} = X_i - F(X_i)/F'(X_i)
|
||||
// For the reciprocal sqrt, we need to find the zero of the function:
|
||||
// F(X) = 1/X^2 - A [which has a zero at X = 1/sqrt(A)]
|
||||
// =>
|
||||
// X_{i+1} = X_i (1.5 - A X_i^2 / 2)
|
||||
// As a result, we precompute A/2 prior to the iteration loop.
|
||||
EVT VT = Op.getValueType();
|
||||
SDLoc DL(Op);
|
||||
SDValue FPThreeHalves = DAG.getConstantFP(1.5, VT);
|
||||
|
||||
AddToWorklist(Est.getNode());
|
||||
|
||||
// We now need 0.5 * Arg which we can write as (1.5 * Arg - Arg) so that
|
||||
// this entire sequence requires only one FP constant.
|
||||
SDValue HalfArg = DAG.getNode(ISD::FMUL, DL, VT, FPThreeHalves, Op);
|
||||
AddToWorklist(HalfArg.getNode());
|
||||
|
||||
HalfArg = DAG.getNode(ISD::FSUB, DL, VT, HalfArg, Op);
|
||||
AddToWorklist(HalfArg.getNode());
|
||||
|
||||
// Newton iterations: Est = Est * (1.5 - HalfArg * Est * Est)
|
||||
for (unsigned i = 0; i < Iterations; ++i) {
|
||||
SDValue NewEst = DAG.getNode(ISD::FMUL, DL, VT, Est, Est);
|
||||
AddToWorklist(NewEst.getNode());
|
||||
|
||||
NewEst = DAG.getNode(ISD::FMUL, DL, VT, HalfArg, NewEst);
|
||||
AddToWorklist(NewEst.getNode());
|
||||
|
||||
NewEst = DAG.getNode(ISD::FSUB, DL, VT, FPThreeHalves, NewEst);
|
||||
AddToWorklist(NewEst.getNode());
|
||||
|
||||
Est = DAG.getNode(ISD::FMUL, DL, VT, Est, NewEst);
|
||||
AddToWorklist(Est.getNode());
|
||||
}
|
||||
|
||||
// We now need 0.5 * Arg which we can write as (1.5 * Arg - Arg) so that
|
||||
// this entire sequence requires only one FP constant.
|
||||
SDValue HalfArg = DAG.getNode(ISD::FMUL, DL, VT, FPThreeHalves, Op);
|
||||
AddToWorklist(HalfArg.getNode());
|
||||
|
||||
HalfArg = DAG.getNode(ISD::FSUB, DL, VT, HalfArg, Op);
|
||||
AddToWorklist(HalfArg.getNode());
|
||||
|
||||
// Newton iterations: Est = Est * (1.5 - HalfArg * Est * Est)
|
||||
for (unsigned i = 0; i < Iterations; ++i) {
|
||||
SDValue NewEst = DAG.getNode(ISD::FMUL, DL, VT, Est, Est);
|
||||
AddToWorklist(NewEst.getNode());
|
||||
|
||||
NewEst = DAG.getNode(ISD::FMUL, DL, VT, HalfArg, NewEst);
|
||||
AddToWorklist(NewEst.getNode());
|
||||
|
||||
NewEst = DAG.getNode(ISD::FSUB, DL, VT, FPThreeHalves, NewEst);
|
||||
AddToWorklist(NewEst.getNode());
|
||||
|
||||
Est = DAG.getNode(ISD::FMUL, DL, VT, Est, NewEst);
|
||||
AddToWorklist(Est.getNode());
|
||||
}
|
||||
}
|
||||
return Est;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user