diff options
| author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2014-09-02 19:02:53 +0000 |
|---|---|---|
| committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2014-09-02 19:02:53 +0000 |
| commit | c1a71217b348e5942cada35d35228a02900b67f6 (patch) | |
| tree | 257b21ad756499f88d69699d829092c8a1050910 /llvm/lib | |
| parent | ac7cbdc9b14fda3d814d696631aefcb5d41ce726 (diff) | |
| download | bcm5719-llvm-c1a71217b348e5942cada35d35228a02900b67f6.tar.gz bcm5719-llvm-c1a71217b348e5942cada35d35228a02900b67f6.zip | |
Fix interference caused by fmul 2, x -> fadd x, x
If an fmul was introduced by lowering, it wouldn't be folded
into a multiply by a constant since the earlier combine would
have replaced the fmul with the fadd.
llvm-svn: 216932
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index e556e74980c..3714aeb65ca 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -6870,6 +6870,27 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) { if (N1CFP && N1CFP->isExactlyValue(1.0)) return N0; + if (DAG.getTarget().Options.UnsafeFPMath) { + // If allowed, fold (fmul (fmul x, c1), c2) -> (fmul x, (fmul c1, c2)) + if (N1CFP && N0.getOpcode() == ISD::FMUL && + N0.getNode()->hasOneUse() && isConstOrConstSplatFP(N0.getOperand(1))) { + SDLoc SL(N); + SDValue MulConsts = DAG.getNode(ISD::FMUL, SL, VT, N0.getOperand(1), N1); + return DAG.getNode(ISD::FMUL, SL, VT, N0.getOperand(0), MulConsts); + } + + // If allowed, fold (fmul (fadd x, x), c) -> (fmul x, (fmul 2.0, c)) + // Undo the fmul 2.0, x -> fadd x, x transformation, since if it occurs + // during an early run of DAGCombiner can prevent folding with fmuls + // inserted during lowering. + if (N0.getOpcode() == ISD::FADD && N0.getOperand(0) == N0.getOperand(1)) { + SDLoc SL(N); + const SDValue Two = DAG.getConstantFP(2.0, VT); + SDValue MulConsts = DAG.getNode(ISD::FMUL, SL, VT, Two, N1); + return DAG.getNode(ISD::FMUL, SDLoc(N), VT, N0.getOperand(0), MulConsts); + } + } + // fold (fmul X, 2.0) -> (fadd X, X) if (N1CFP && N1CFP->isExactlyValue(+2.0)) return DAG.getNode(ISD::FADD, SDLoc(N), VT, N0, N0); @@ -6890,14 +6911,6 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) { } } - // If allowed, fold (fmul (fmul x, c1), c2) -> (fmul x, (fmul c1, c2)) - if (Options.UnsafeFPMath && N1CFP && N0.getOpcode() == ISD::FMUL && - N0.getNode()->hasOneUse() && isConstOrConstSplatFP(N0.getOperand(1))) { - return DAG.getNode(ISD::FMUL, SDLoc(N), VT, N0.getOperand(0), - DAG.getNode(ISD::FMUL, SDLoc(N), VT, - N0.getOperand(1), N1)); - } - return SDValue(); } |

