Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4438,28 +4438,42 @@ N1.getValueType() == VT && "Binary operator types must match!"); break; case ISD::FADD: + if (getTarget().Options.UnsafeFPMath || + Flags.hasNoSignedZeros()) { + // x+0 --> x + if (N2CFP && N2CFP->getValueAPF().isZero()) + return N1; + } + assert(VT.isFloatingPoint() && "This operator only applies to FP types!"); + assert(N1.getValueType() == N2.getValueType() && + N1.getValueType() == VT && "Binary operator types must match!"); + break; case ISD::FSUB: + // x-0 --> x + if (N2CFP && N2CFP->getValueAPF().isZero()) { + if (!N2CFP->getValueAPF().isNegative() && !N1CFP) { + // For variant fsub with positive zero only, + // we will leave x-(-0.0) untranslated to fsub as we do not know if x is equal + // to -0.0, otherwise try folding below if both values are constant. + return N1; + } + } + assert(VT.isFloatingPoint() && "This operator only applies to FP types!"); + assert(N1.getValueType() == N2.getValueType() && + N1.getValueType() == VT && "Binary operator types must match!"); + break; case ISD::FMUL: + if (getTarget().Options.UnsafeFPMath || + (Flags.hasNoNaNs() && Flags.hasNoSignedZeros())) { + // x*0 --> 0 + if (N2CFP && N2CFP->isZero()) + return N2; + } else if (N2CFP && N2CFP->isExactlyValue(1.0)) { + // x*1 --> x + return N1; + } case ISD::FDIV: case ISD::FREM: - if (getTarget().Options.UnsafeFPMath) { - if (Opcode == ISD::FADD) { - // x+0 --> x - if (N2CFP && N2CFP->getValueAPF().isZero()) - return N1; - } else if (Opcode == ISD::FSUB) { - // x-0 --> x - if (N2CFP && N2CFP->getValueAPF().isZero()) - return N1; - } else if (Opcode == ISD::FMUL) { - // x*0 --> 0 - if (N2CFP && N2CFP->isZero()) - return N2; - // x*1 --> x - if (N2CFP && N2CFP->isExactlyValue(1.0)) - return N1; - } - } assert(VT.isFloatingPoint() && "This operator only applies to FP types!"); assert(N1.getValueType() == N2.getValueType() && N1.getValueType() == VT && "Binary operator types must match!"); Index: test/CodeGen/X86/fp-fold.ll =================================================================== --- test/CodeGen/X86/fp-fold.ll +++ test/CodeGen/X86/fp-fold.ll @@ -46,14 +46,9 @@ } define float @fsub_zero(float %x) { -; STRICT-LABEL: fsub_zero: -; STRICT: # %bb.0: -; STRICT-NEXT: addss {{.*}}(%rip), %xmm0 -; STRICT-NEXT: retq -; -; UNSAFE-LABEL: fsub_zero: -; UNSAFE: # %bb.0: -; UNSAFE-NEXT: retq +; ANY-LABEL: fsub_zero: +; ANY: # %bb.0: +; ANY-NEXT: retq %r = fsub float %x, 0.0 ret float %r }