Index: lib/Transforms/Scalar/SCCP.cpp =================================================================== --- lib/Transforms/Scalar/SCCP.cpp +++ lib/Transforms/Scalar/SCCP.cpp @@ -857,10 +857,18 @@ LatticeVal &IV = ValueState[&I]; if (IV.isOverdefined()) return; - if (V1State.isConstant() && V2State.isConstant()) - return markConstant(IV, &I, - ConstantExpr::get(I.getOpcode(), V1State.getConstant(), - V2State.getConstant())); + if (V1State.isConstant() && V2State.isConstant()) { + FastMathFlags FMF; + + if (isa(&I)) { + FMF = I.getFastMathFlags(); + } + + if (Constant *C = ConstantExpr::get(I.getOpcode(), V1State.getConstant(), + V2State.getConstant(), 0, nullptr, + FMF, true)) + return markConstant(IV, &I, C); + } // If something is undef, wait for it to resolve. if (!V1State.isOverdefined() && !V2State.isOverdefined()) Index: test/Transforms/SCCP/do-not-convert-fpop-to-constexpr.ll =================================================================== --- /dev/null +++ test/Transforms/SCCP/do-not-convert-fpop-to-constexpr.ll @@ -0,0 +1,24 @@ +; fmuls shouldn't be converted to constant expressions. +; RUN: opt < %s -sccp -S -enable-except-access-fp-math | FileCheck %s + +define double @do-not-convert-fpop-to-constexpr(double %x) { +; CHECK-LABEL: @do-not-convert-fpop-to-constexpr( +; CHECK: fmul +; CHECK: fmul +; CHECK-NOT: select +entry: + %cmp = fcmp oeq double %x, 0.000000e+00 + br i1 %cmp, label %cond.true, label %cond.false + +cond.true: + %val.true = fmul kexc double 1.000000e+300, 1.000000e+300 + br label %cond.end + +cond.false: + %val.false = fmul kexc double 1.000000e-300, 1.000000e-300 + br label %cond.end + +cond.end: + %cond = phi double [ %val.true, %cond.true ], [ %val.false, %cond.false ] + ret double %cond +}