Repository: JuliaLang/julia
File: test/fastmath.jl (Julia)

Code before:
    # 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
# issue #53857
@testset "fast_pow" begin
    n = Int64(2)^52
    @test @fastmath (1 + 1 / n) ^ n ≈ ℯ
    @test @fastmath (1 + 1 / n) ^ 4503599627370496 ≈ ℯ
end

# Test that x^2 is inlined to fmul for all float types (issue #60639)
@testset "pow_fast inlining for literal powers" begin
    for T in (Float16, Float32, Float64)
        f(x) = @fastmath x^2
        llvm = sprint(code_llvm, f, (T,))
        # Should be inlined to fmul, not call power_by_squaring
        @test occursin("fmul", llvm)
        @test !occursin("power_by_squaring", llvm)
    end
end

@testset "sincos fall-backs" begin
    struct FloatWrapper
        inner::Float64
    end
    Base.sin(outer::FloatWrapper) = sin(outer.inner)
    Base.cos(outer::FloatWrapper) = cos(outer.inner)
    for zilch in (FloatWrapper(0.0), 0, 0 + 0 * im)
        @test (@fastmath sincos(zilch)) == (0, 1)
    end
end

@testset "non-numeric fallbacks" begin
    @test (@fastmath :(:sin)) == :(:sin)
    @test (@fastmath "a" * "b") == "ab"
    @test (@fastmath "a" ^ 2) == "aa"
end

Review comment (suggestion):
also test that `@fastmath x^y` produces approximately correct  results for Float32/Float16 for both exponents that fit and that don't fit within Int32.

Code after:
    # 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
# issue #53857
@testset "fast_pow" begin
    n = Int64(2)^52
    @test @fastmath (1 + 1 / n) ^ n ≈ ℯ
    @test @fastmath (1 + 1 / n) ^ 4503599627370496 ≈ ℯ
end

# Test that x^2 is inlined to fmul for all float types (issue #60639)
@testset "pow_fast inlining for literal powers" begin
    for T in (Float16, Float32, Float64)
        f(x) = @fastmath x^2
        llvm = sprint(code_llvm, f, (T,))
        # Should be inlined to fmul, not call power_by_squaring
        @test occursin("fmul", llvm)
        @test !occursin("power_by_squaring", llvm)
    end
end

# Test correctness of pow_fast for Float32/Float16 with various exponents (issue #60639)
@testset "pow_fast correctness" begin
    for T in (Float16, Float32)
        x = T(2.5)
        # Exponents that fit in Int32
        @test (@fastmath x^2) ≈ x^2
        @test (@fastmath x^10) ≈ x^10
        @test (@fastmath x^(-3)) ≈ x^(-3)
        # Exponents that don't fit in Int32
        big_exp = Int64(2)^40
        @test (@fastmath x^big_exp) ≈ x^big_exp
    end
end

@testset "sincos fall-backs" begin
    struct FloatWrapper