diff --git a/base/fastmath.jl b/base/fastmath.jl index a34a4ca66e06b..28a7852640ba9 100644 --- a/base/fastmath.jl +++ b/base/fastmath.jl @@ -101,9 +101,12 @@ const rewrite_op = function make_fastmath(expr::Expr) if expr.head === :quote return expr - elseif expr.head === :call && expr.args[1] === :^ && expr.args[3] isa Integer - # mimic Julia's literal_pow lowering of literal integer powers - return Expr(:call, :(Base.FastMath.pow_fast), make_fastmath(expr.args[2]), Val{expr.args[3]}()) + elseif expr.head === :call && expr.args[1] === :^ + ea = expr.args + if length(ea) >= 3 && isa(ea[3], Int) + # mimic Julia's literal_pow lowering of literal integer powers + return Expr(:call, :(Base.FastMath.pow_fast), make_fastmath(ea[2]), Val(ea[3])) + end end op = get(rewrite_op, expr.head, :nothing) if op !== :nothing @@ -364,6 +367,10 @@ for f in (:^, :atan, :hypot, :log) # fall-back implementation that applies after promotion $f_fast(x::T, y::T) where {T<:Number} = $f(x, y) end + # Issue 53886 - avoid promotion of Int128 etc to be consistent with non-fastmath + if f === :^ + @eval $f_fast(x::Number, y::Integer) = $f(x, y) + end end # Reductions diff --git a/test/fastmath.jl b/test/fastmath.jl index 34744f325ad7f..120c0ece685bb 100644 --- a/test/fastmath.jl +++ b/test/fastmath.jl @@ -256,6 +256,22 @@ end @testset "literal powers" begin @test @fastmath(2^-2) == @fastmath(2.0^-2) == 0.25 + # Issue #53817 + # Note that exponent -2^63 fails testing because of issue #53881 + # Therefore we test with -(2^63-1). For Int == Int32 there is an analogue restriction. + # See also PR #53860. + if Int == Int64 + @test @fastmath(2^-9223372036854775807) === 0.0 + @test_throws DomainError @fastmath(2^-9223372036854775809) + @test @fastmath(1^-9223372036854775807) isa Float64 + @test @fastmath(1^-9223372036854775809) isa Int + elseif Int == Int32 + @test @fastmath(2^-2147483647) === 0.0 + @test_throws DomainError @fastmath(2^-2147483649) + @test @fastmath(1^-2147483647) isa Float64 + @test @fastmath(1^-2147483649) isa Int + end + @test_throws MethodError @fastmath(^(2)) end @testset "sincos fall-backs" begin