diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 23 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 15 | 
2 files changed, 30 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index f7c1d061c6b..e494da3644d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/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/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index a08856022ab..29744862089 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/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;  | 

