Skip to content

Commit

Permalink
Make gcd/lcm effect-free by using LazyString (#44935)
Browse files Browse the repository at this point in the history
  • Loading branch information
tkf authored and aviatesk committed Jul 25, 2022
1 parent f3bc6bf commit a382f32
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 5 deletions.
9 changes: 5 additions & 4 deletions base/checked.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,10 @@ function checked_abs end

function checked_abs(x::SignedInt)
r = ifelse(x<0, -x, x)
r<0 && throw(OverflowError(string("checked arithmetic: cannot compute |x| for x = ", x, "::", typeof(x))))
r
end
r<0 || return r
msg = LazyString("checked arithmetic: cannot compute |x| for x = ", x, "::", typeof(x))
throw(OverflowError(msg))
end
checked_abs(x::UnsignedInt) = x
checked_abs(x::Bool) = x

Expand Down Expand Up @@ -151,7 +152,7 @@ end


throw_overflowerr_binaryop(op, x, y) = (@noinline;
throw(OverflowError(Base.invokelatest(string, x, " ", op, " ", y, " overflowed for type ", typeof(x)))))
throw(OverflowError(LazyString(x, " ", op, " ", y, " overflowed for type ", typeof(x)))))

"""
Base.checked_add(x, y)
Expand Down
3 changes: 2 additions & 1 deletion base/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ function gcd(a::T, b::T) where T<:BitInteger
signbit(r) && __throw_gcd_overflow(a, b)
return r
end
@noinline __throw_gcd_overflow(a, b) = throw(OverflowError("gcd($a, $b) overflows"))
@noinline __throw_gcd_overflow(a, b) =
throw(OverflowError(LazyString("gcd(", a, ", ", b, ") overflows")))

# binary GCD (aka Stein's) algorithm
# about 1.7x (2.1x) faster for random Int64s (Int128s)
Expand Down
7 changes: 7 additions & 0 deletions test/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

using Random

is_effect_free(args...) = Core.Compiler.is_effect_free(Base.infer_effects(args...))

@testset "gcd/lcm" begin
# All Integer data types take different code paths -- test all
# TODO: Test gcd and lcm for BigInt.
Expand Down Expand Up @@ -146,6 +148,11 @@ using Random
@test gcd(0xf, 20) == 5
@test gcd(UInt32(6), Int8(-50)) == 2
@test gcd(typemax(UInt), -16) == 1

@testset "effects" begin
@test is_effect_free(gcd, Tuple{Int,Int})
@test is_effect_free(lcm, Tuple{Int,Int})
end
end

@testset "gcd/lcm for arrays" begin
Expand Down

0 comments on commit a382f32

Please sign in to comment.