diff options
author | Dan Gohman <gohman@apple.com> | 2009-01-22 21:58:43 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-01-22 21:58:43 +0000 |
commit | 760f86f3395750ef6d03ecfe6f82d2867fbf568b (patch) | |
tree | bdf1046c3f79e9422ab88ada0c421ab4a687722c /lib/CodeGen | |
parent | edc4d69917df7dc34543adf719d5c93249fd5e27 (diff) | |
download | external_llvm-760f86f3395750ef6d03ecfe6f82d2867fbf568b.zip external_llvm-760f86f3395750ef6d03ecfe6f82d2867fbf568b.tar.gz external_llvm-760f86f3395750ef6d03ecfe6f82d2867fbf568b.tar.bz2 |
Don't create ISD::FNEG nodes after legalize if they aren't legal.
Simplify x+0 to x in unsafe-fp-math mode. This avoids a bunch of
redundant work in many cases, because in unsafe-fp-math mode,
ISD::FADD with a constant is considered free to negate, so the
DAGCombiner often negates x+0 to -0-x thinking it's free, when
in reality the end result is -x, which is more expensive than x.
Also, combine x*0 to 0.
This fixes PR3374.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62789 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 23 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 15 |
2 files changed, 30 insertions, 8 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index f7c1d06..e494da3 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3814,6 +3814,9 @@ SDValue DAGCombiner::visitFADD(SDNode *N) { // canonicalize constant to RHS if (N0CFP && !N1CFP) return DAG.getNode(ISD::FADD, VT, N1, N0); + // fold (A + 0) -> A + if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero()) + return N0; // fold (A + (-B)) -> A-B if (isNegatibleForFree(N1, LegalOperations) == 2) return DAG.getNode(ISD::FSUB, VT, N0, @@ -3852,7 +3855,8 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) { if (UnsafeFPMath && N0CFP && N0CFP->getValueAPF().isZero()) { if (isNegatibleForFree(N1, LegalOperations)) return GetNegatedExpression(N1, DAG, LegalOperations); - return DAG.getNode(ISD::FNEG, VT, N1); + if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT)) + return DAG.getNode(ISD::FNEG, VT, N1); } // fold (A-(-B)) -> A+B if (isNegatibleForFree(N1, LegalOperations)) @@ -3881,12 +3885,16 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) { // canonicalize constant to RHS if (N0CFP && !N1CFP) return DAG.getNode(ISD::FMUL, VT, N1, N0); + // fold (A * 0) -> 0 + if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero()) + return N1; // fold (fmul X, 2.0) -> (fadd X, X) if (N1CFP && N1CFP->isExactlyValue(+2.0)) return DAG.getNode(ISD::FADD, VT, N0, N0); // fold (fmul X, -1.0) -> (fneg X) if (N1CFP && N1CFP->isExactlyValue(-1.0)) - return DAG.getNode(ISD::FNEG, VT, N0); + if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT)) + return DAG.getNode(ISD::FNEG, VT, N0); // -X * -Y -> X*Y if (char LHSNeg = isNegatibleForFree(N0, LegalOperations)) { @@ -3970,10 +3978,13 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) { const APFloat& V = N1CFP->getValueAPF(); // copysign(x, c1) -> fabs(x) iff ispos(c1) // copysign(x, c1) -> fneg(fabs(x)) iff isneg(c1) - if (!V.isNegative()) - return DAG.getNode(ISD::FABS, VT, N0); - else - return DAG.getNode(ISD::FNEG, VT, DAG.getNode(ISD::FABS, VT, N0)); + if (!V.isNegative()) { + if (!LegalOperations || TLI.isOperationLegal(ISD::FABS, VT)) + return DAG.getNode(ISD::FABS, VT, N0); + } else { + if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT)) + return DAG.getNode(ISD::FNEG, VT, DAG.getNode(ISD::FABS, VT, N0)); + } } // copysign(fabs(x), y) -> copysign(x, y) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index a088560..2974486 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -27,6 +27,7 @@ #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/CommandLine.h" @@ -2391,16 +2392,26 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, case ISD::UREM: case ISD::MULHU: case ISD::MULHS: - assert(VT.isInteger() && "This operator does not apply to FP types!"); - // fall through case ISD::MUL: case ISD::SDIV: case ISD::SREM: + assert(VT.isInteger() && "This operator does not apply to FP types!"); + // fall through case ISD::FADD: case ISD::FSUB: case ISD::FMUL: case ISD::FDIV: case ISD::FREM: + if (UnsafeFPMath && Opcode == ISD::FADD) { + // 0+x --> x + if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N1)) + if (CFP->getValueAPF().isZero()) + return N2; + // x+0 --> x + if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N2)) + if (CFP->getValueAPF().isZero()) + return N1; + } assert(N1.getValueType() == N2.getValueType() && N1.getValueType() == VT && "Binary operator types must match!"); break; |