/
githubmirror
/
julia
Обзор
Документация
Войти
/
githubmirror
/
julia
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
test/llvmcall2.jl
137 строк
6 KB
Jameson Nash
[jitlayers] add missing JD parameter to remaining external API call (#60988)
12 май 2026, 03:50
Не верифицирован
12 май 2026, 03:50
d5f1466
Код
Авторство
О чём код?
# This file is a part of Julia. License is MIT: https://julialang.org/license using InteractiveUtils: code_llvm using libLLVM_jll function declared_floor(x::Float64) return ccall("llvm.floor.f64", llvmcall, Float64, (Float64,), x) end @test declared_floor(4.2) == 4.0 ir = sprint(code_llvm, declared_floor, Tuple{Float64}) @test occursin("call double @llvm.floor.f64", ir) # should be inlined function doubly_declared_floor(x::Float64) a = ccall("llvm.floor.f64", llvmcall, Float64, (Float64,), x) b = ccall("llvm.floor.f64", llvmcall, Float64, (Float64,), x + 1) - 1 return a + b end @test doubly_declared_floor(4.2) == 8.0 function doubly_declared2_trunc(x::Float64) a = ccall("llvm.trunc.f64", llvmcall, Float64, (Float64,), x) b = ccall("llvm.trunc.f64", llvmcall, Float64, (Float64,), x + 1) - 1 return a + b end @test doubly_declared2_trunc(4.2) == 8.0 # Test for single line function declared_ceil(x::Float64) return ccall("llvm.ceil.f64", llvmcall, Float64, (Float64,), x) end @test declared_ceil(4.2) == 5.0 # Test for multiple lines function ceilfloor(x::Float64) a = ccall("llvm.ceil.f64", llvmcall, Float64, (Float64,), x) b = ccall("llvm.floor.f64", llvmcall, Float64, (Float64,), a) return b end @test ceilfloor(7.4) == 8.0 let err = ErrorException("llvmcall only supports intrinsic calls") # support for calling external functions @test_throws err @eval ccall("time", llvmcall, Cvoid, (Ptr{Cvoid},), C_NULL) g() = ccall("extern time", llvmcall, Cvoid, (Ptr{Cvoid},), C_NULL) g() @test_throws err @eval ccall("extern llvm.floor", llvmcall, Float64, (Float64,), 0.0) # support for mangling @test (@eval ccall("llvm.floor.f64", llvmcall, Float64, (Float64,), 0.0)) === 0.0 @test (@eval ccall("llvm.floor", llvmcall, Float64, (Float64,), 0.0), ccall("llvm.floor", llvmcall, Float32, (Float32,), 0.0)) === (0.0, 0.0f0) @test_throws err @eval ccall("llvm.floor.f64", llvmcall, Float32, (Float64,), 0.0) @test_throws err @eval ccall("llvm.floor.f64", llvmcall, Float32, (Float32,), 0.0f0) @test_throws err @eval ccall("llvm.floor.f64", llvmcall, Float64, (Float32,), 0.0f0) @test_throws err @eval ccall("llvm.floor.f64", llvmcall, Float64, (Int,), 0) @test_throws err @eval ccall("llvm.floor.f64", llvmcall, Int, (Int,), 0) @test_throws err @eval ccall("llvm.floor", llvmcall, Float64, (Float32,), 0.0f0) @test_throws err @eval ccall("llvm.floor", llvmcall, Float64, (Int,), 0) @test_throws err @eval ccall("llvm.floor", llvmcall, Int, (Int,), 0) @test_throws err (@eval ccall("llvm.floor.f64", llvmcall, Float64, (Float64, Float64...,), 0.0)) === 0.0 @test_throws err (@eval ccall("llvm.floor", llvmcall, Float64, (Float64, Float64...,), 0.0)) === 0.0 end # Test basic JIT access and info functions @testset "JLJIT API" begin function JLJITGetJuliaOJIT() ccall(:JLJITGetJuliaOJIT, Ptr{Cvoid}, ()) end function JLJITGetTripleString(JIT) ccall(:JLJITGetTripleString, Cstring, (Ptr{Cvoid},), JIT) end function JLJITGetDataLayoutString(JIT) ccall(:JLJITGetDataLayoutString, Cstring, (Ptr{Cvoid},), JIT) end function JLJITGetGlobalPrefix(JIT) ccall(:JLJITGetGlobalPrefix, Cchar, (Ptr{Cvoid},), JIT) end function JLJITMangleAndIntern(JIT, name) ccall(:JLJITMangleAndIntern, Ptr{Cvoid}, (Ptr{Cvoid}, Cstring), JIT, name) end function JLJITCreateJITDylib(JIT, name) ccall(:JLJITCreateJITDylib, Ptr{Cvoid}, (Ptr{Cvoid}, Cstring), JIT, name) end function JLJITJDLookup(JIT, JD, result_ptr, name, external_jd_only) ccall(:JLJITJDLookup, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{UInt64}, Cstring, Cint), JIT, JD, result_ptr, name, external_jd_only) end function LLVMGetErrorMessage(err) errp = ccall((:LLVMGetErrorMessage, libLLVM_jll.libLLVM), Cstring, (Ptr{Cvoid},), err) errs = unsafe_string(errp) ccall((:LLVMDisposeErrorMessage, libLLVM_jll.libLLVM), Cvoid, (Cstring,), errp) return errs end jit = JLJITGetJuliaOJIT() @test jit != C_NULL str = JLJITGetTripleString(jit) jl_str = unsafe_string(str) @test length(jl_str) > 4 @test 2 <= count("-", jl_str) <= 4 dl_str = JLJITGetDataLayoutString(jit) jl_dl_str = unsafe_string(dl_str) @test length(jl_dl_str) > 1 @test occursin("-", jl_dl_str) @test occursin(":", jl_dl_str) prefix = Char(JLJITGetGlobalPrefix(jit)) @test prefix == '\0' || prefix == '_' # Common prefixes are no prefix or underscore mangled = JLJITMangleAndIntern(jit, "my_symbol") @test mangled != C_NULL jd = JLJITCreateJITDylib(jit, "TestJITDylib") @test jd != C_NULL # look up a symbol from GlobalJD via JD result = Ref{UInt64}(0) err = JLJITJDLookup(jit, jd, result, "jl_get_ptls_states", 0) @test err == C_NULL @test result[] != 0 # Should find the symbol err = JLJITJDLookup(jit, jd, result, "jl_get_ptls_states", 1) @test err != C_NULL @test LLVMGetErrorMessage(err) ∈ ("Symbols not found: [ jl_get_ptls_states ]", "Symbols not found: [ _jl_get_ptls_states ]") end # boolean structs const NT4I = NTuple{4, VecElement{Int}} const NT4B = NTuple{4, VecElement{Bool}} f_nt4b(x, y) = ccall("llvm.sadd.with.overflow", llvmcall, Pair{NT4B, NT4B}, (NT4B, NT4B), x, y) f_nt4i(x, y) = ccall("llvm.sadd.with.overflow", llvmcall, Pair{NT4I, NT4B}, (NT4I, NT4I), x, y) @test f_nt4b((false, true, false, true), (false, false, true, true)) === (NT4B((false, true, true, false)) => NT4B((false, false, false, true))) @test f_nt4i((typemin(Int), 0, typemax(Int), typemax(Int)), (-1, typemax(Int),-1, 1)) === (NT4I((typemax(Int), typemax(Int), typemax(Int)-1, typemin(Int))) => NT4B((true, false, false, true)))