diff --git a/test/test_Cthulhu.jl b/test/test_Cthulhu.jl index 6eaccc27..76ce31fa 100644 --- a/test/test_Cthulhu.jl +++ b/test/test_Cthulhu.jl @@ -83,16 +83,46 @@ end calltwice(c) = twice(c[1]) callsites = find_callsites_by_ftt(calltwice, Tuple{Vector{Float64}}) - @test length(callsites) == 1 && callsites[1].head === :invoke - io = IOBuffer() - print(io, callsites[1]) - @test occursin("invoke twice(::Float64)::Float64", String(take!(io))) + @static if VERSION ≥ v"1.11.0-DEV.753" + @test any(callsite) do callsite + callsite.head === :invoke || return false + io = IOBuffer() + print(io, callsite) + return occursin("invoke twice(::Float64)::Float64", String(take!(io))) + end + @test any(callsite) do callsite + callsite.head === :invoke || return false + io = IOBuffer() + print(io, callsite) + return occursin("invoke throw_boundserror", String(take!(io))) + end + else + @test length(callsites) == 1 && callsites[1].head === :invoke + io = IOBuffer() + print(io, callsites[1]) + @test occursin("invoke twice(::Float64)::Float64", String(take!(io))) + end callsites = find_callsites_by_ftt(calltwice, Tuple{Vector{AbstractFloat}}) - @test length(callsites) == 1 && callsites[1].head === :call - io = IOBuffer() - print(io, callsites[1]) - @test occursin("call twice(::AbstractFloat)", String(take!(io))) + @static if VERSION ≥ v"1.11.0-DEV.753" + @test any(callsite) do callsite + callsite.head === :call || return false + io = IOBuffer() + print(io, callsite) + return occursin("invoke twice(::AbstractFloat)", String(take!(io))) + end + @test any(callsite) do callsite + callsite.head === :invoke || return false + io = IOBuffer() + print(io, callsite) + return occursin("invoke throw_boundserror", String(take!(io))) + end + else + @test length(callsites) == 1 && callsites[1].head === :call + io = IOBuffer() + print(io, callsites[1]) + @test occursin("call twice(::AbstractFloat)", String(take!(io))) + end # Note the failure of `callinfo` to properly handle specialization @test_broken Cthulhu.callinfo(Tuple{typeof(twice), AbstractFloat}, AbstractFloat) isa Cthulhu.MultiCallInfo @@ -130,28 +160,33 @@ let callsites = find_callsites_by_ftt(call_by_apply, Tuple{Tuple{Int}}; optimize @test length(callsites) == 1 end +Base.@propagate_inbounds _boundscheck_dce(x) = @boundscheck error() +boundscheck_dce_inbounds(x) = @inbounds _boundscheck_dce(x) +boundscheck_dce(x) = _boundscheck_dce(x) + @testset "DCE & boundscheck" begin - M = Module() - @eval M begin - Base.@propagate_inbounds function f(x) - @boundscheck error() + @static if VERSION ≥ v"1.11.0-DEV.377" + # no boundscheck elimination on Julia-level compilation + for f in (boundscheck_dce_inbounds, boundscheck_dce) + let (; src) = cthulhu_info(f, Tuple{Vector{Float64}}) + @test count(src.stmts.stmt) do stmt + isexpr(stmt, :boundscheck) + end == 1 + end end - g(x) = @inbounds f(x) - h(x) = f(x) - end - - let (; src) = cthulhu_info(M.g, Tuple{Vector{Float64}}) - stmts = @static VERSION < v"1.11.0-DEV.258" ? src.stmts.inst : src.stmts.stmt - @test all(stmts) do stmt - isa(stmt, Core.GotoNode) || (isa(stmt, Core.ReturnNode) && isdefined(stmt, :val)) + else + let (; src) = cthulhu_info(boundscheck_dce_inbounds, Tuple{Vector{Float64}}) + stmts = @static VERSION < v"1.11.0-DEV.258" ? src.stmts.inst : src.stmts.stmt + @test all(stmts) do stmt + isa(stmt, Core.GotoNode) || (isa(stmt, Core.ReturnNode) && isdefined(stmt, :val)) + end + end + let (; src) = cthulhu_info(boundscheck_dce, Tuple{Vector{Float64}}) + stmts = @static VERSION < v"1.11.0-DEV.258" ? src.stmts.inst : src.stmts.stmt + @test count(!isnothing, stmts) == 2 + stmt = stmts[end] + @test isa(stmt, Core.ReturnNode) && !isdefined(stmt, :val) end - end - - let (; src) = cthulhu_info(M.h, Tuple{Vector{Float64}}) - stmts = @static VERSION < v"1.11.0-DEV.258" ? src.stmts.inst : src.stmts.stmt - @test count(!isnothing, stmts) == 2 - stmt = stmts[end] - @test isa(stmt, Core.ReturnNode) && !isdefined(stmt, :val) end end