diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 7e8e46fba50..e4b24f1aaff 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3853,6 +3853,9 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) { // fold (fsub c1, c2) -> c1-c2 if (N0CFP && N1CFP && VT != MVT::ppcf128) return DAG.getNode(ISD::FSUB, VT, N0, N1); + // fold (A-0) -> A + if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero()) + return N0; // fold (0-B) -> -B if (UnsafeFPMath && N0CFP && N0CFP->getValueAPF().isZero()) { if (isNegatibleForFree(N1, LegalOperations)) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 29744862089..6d1fdd23407 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2402,15 +2402,22 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, case ISD::FMUL: case ISD::FDIV: case ISD::FREM: - if (UnsafeFPMath && Opcode == ISD::FADD) { - // 0+x --> x - if (ConstantFPSDNode *CFP = dyn_cast(N1)) - if (CFP->getValueAPF().isZero()) - return N2; - // x+0 --> x - if (ConstantFPSDNode *CFP = dyn_cast(N2)) - if (CFP->getValueAPF().isZero()) - return N1; + if (UnsafeFPMath) { + if (Opcode == ISD::FADD) { + // 0+x --> x + if (ConstantFPSDNode *CFP = dyn_cast(N1)) + if (CFP->getValueAPF().isZero()) + return N2; + // x+0 --> x + if (ConstantFPSDNode *CFP = dyn_cast(N2)) + if (CFP->getValueAPF().isZero()) + return N1; + } else if (Opcode == ISD::FSUB) { + // x-0 --> x + if (ConstantFPSDNode *CFP = dyn_cast(N2)) + if (CFP->getValueAPF().isZero()) + return N1; + } } assert(N1.getValueType() == N2.getValueType() && N1.getValueType() == VT && "Binary operator types must match!");