diff --git a/base/compiler/optimize.jl b/base/compiler/optimize.jl index 120fc89754a11..db66e63d407bc 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -408,7 +408,7 @@ function finish(interp::AbstractInterpreter, opt::OptimizationState, # otherwise we might skip throwing errors (issue #20704) # TODO: Improve this analysis; if a function is marked @pure we should really # only care about certain errors (e.g. method errors and type errors). - if length(ir.stmts) < 10 + if length(ir.stmts) < 15 proven_pure = true for i in 1:length(ir.stmts) node = ir.stmts[i] @@ -624,7 +624,8 @@ function is_pure_intrinsic_infer(f::IntrinsicFunction) end # whether `f` is effect free if nothrow -intrinsic_effect_free_if_nothrow(f) = f === Intrinsics.pointerref || is_pure_intrinsic_infer(f) +intrinsic_effect_free_if_nothrow(f) = f === Intrinsics.pointerref || + f === Intrinsics.have_fma || is_pure_intrinsic_infer(f) ## Computing the cost of a function body diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index 65a86f262d9b3..1967b237ca009 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -1815,6 +1815,10 @@ function intrinsic_nothrow(f::IntrinsicFunction, argtypes::Array{Any, 1}) xty = widenconst(argtypes[2]) return isconcrete && isprimitivetype(ty) && isprimitivetype(xty) end + if f === Intrinsics.have_fma + ty, isexact, isconcrete = instanceof_tfunc(argtypes[1]) + return isconcrete && isprimitivetype(ty) + end # The remaining intrinsics are math/bits/comparison intrinsics. They work on all # primitive types of the same type. isshift = f === shl_int || f === lshr_int || f === ashr_int diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index a2f6ddc99409a..035c291b4be8f 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -880,3 +880,7 @@ end @test count(iscall((src,UnionAll)), src.code) == 0 end end + +# have_fma elimination inside ^ +f_pow() = ^(2.0, -1.0) +@test fully_eliminated(f_pow, Tuple{})