Skip to content

Commit

Permalink
fix pow_fast(x, y) for large integer y (JuliaLang#54512)
Browse files Browse the repository at this point in the history
Fixes JuliaLang#53857

For `x::Union{Float32,Float64}` and `y::Integer` with `y % Int32 != y` a
stack trace appears when calling `@fastmath x^y`.

This fix calls `x^y` in those cases, while leaving the other cases as
is.
  • Loading branch information
KlausC authored and lazarusA committed Jul 12, 2024
1 parent 14b9726 commit 5afa273
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 2 deletions.
8 changes: 6 additions & 2 deletions base/fastmath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,12 @@ exp10_fast(x::Union{Float32,Float64}) = Base.Math.exp10_fast(x)

# builtins

pow_fast(x::Float32, y::Integer) = ccall("llvm.powi.f32.i32", llvmcall, Float32, (Float32, Int32), x, y)
pow_fast(x::Float64, y::Integer) = ccall("llvm.powi.f64.i32", llvmcall, Float64, (Float64, Int32), x, y)
function pow_fast(x::Float64, y::Integer)
z = y % Int32
z == y ? pow_fast(x, z) : x^y
end
pow_fast(x::Float32, y::Integer) = x^y
pow_fast(x::Float64, y::Int32) = ccall("llvm.powi.f64.i32", llvmcall, Float64, (Float64, Int32), x, y)
pow_fast(x::FloatTypes, ::Val{p}) where {p} = pow_fast(x, p) # inlines already via llvm.powi
@inline pow_fast(x, v::Val) = Base.literal_pow(^, x, v)

Expand Down
6 changes: 6 additions & 0 deletions test/fastmath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,12 @@ end
end
@test_throws MethodError @fastmath(^(2))
end
# issue #53857
@testset "fast_pow" begin
n = Int64(2)^52
@test @fastmath (1 + 1 / n) ^ n
@test @fastmath (1 + 1 / n) ^ 4503599627370496
end

@testset "sincos fall-backs" begin
struct FloatWrapper
Expand Down

0 comments on commit 5afa273

Please sign in to comment.