summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2014-09-30 20:44:23 +0000
committerSanjay Patel <spatel@rotateright.com>2014-09-30 20:44:23 +0000
commitab7f460bca19440745b156fbb655a9d5d0b48ac8 (patch)
tree0fa72c869594421fe3fe3564f70934c4a48148e8 /llvm/lib/CodeGen/SelectionDAG
parent89fd66813b0115faa49b3490df1dce84e9cc20ec (diff)
downloadbcm5719-llvm-ab7f460bca19440745b156fbb655a9d5d0b48ac8.tar.gz
bcm5719-llvm-ab7f460bca19440745b156fbb655a9d5d0b48ac8.zip
Use the target-specified iteration count to opt out of any further refinement of an estimate. NFC.
llvm-svn: 218700
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp122
1 files changed, 62 insertions, 60 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 407a8747746..03a1b71407e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -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);
-
- 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);
+ 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());
+ }
+ }
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);
-
- 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);
+ 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());
+ }
+ }
return Est;
}
OpenPOWER on IntegriCloud