Skip to content

Odd difference in ccall'ing function from a parameterized method versus one with hardcoded types #29400

@pkofod

Description

@pkofod

Sorry for the slightly weird title, but I have no idea what the problem is, so maybe we can change the title when someone more clever than I am stops by :)

julia> __ldexp_exp(x::Float64, i::T) where T = ccall(("__ldexp_exp", Base.Math.libm), Float64, (Float64, T), x, i)
__ldexp_exp (generic function with 1 method)

julia> __ldexp_exp(0.245,-1)
2.4519928653854222e55

julia> Base.Math._ldexp_exp(0.245,-1)
2.4519928653854222e55

julia> ccall(("__ldexp_exp", Base.Math.libm), Float64, (Float64, typeof(-1)), 0.245, -1)
1.9872231581449074e233

See, I'm trying to create a Julia port of what is called here

_ldexp_exp(x::Float64, i::T) where T = ccall(("__ldexp_exp", libm), Float64, (Float64, T), x, i)
but this weird problem showed up. _ldexp_exp is defined here https://github.com/JuliaMath/openlibm/blob/cca41bc1abd01804afa4862bbd2c79cc9803171a/src/k_exp.c#L75

The following thing might help people who know about this stuff decipher what's going on

julia> __ldexp_exp_T(x::Float64, i::T) where T = ccall(("__ldexp_exp", Base.Math.libm), Float64, (Float64, T), x, i)
__ldexp_exp_T (generic function with 1 method)

julia> __ldexp_exp(x::Float64, i::T) where T = ccall(("__ldexp_exp", Base.Math.libm), Float64, (Float64, typeof(-1)), x, i)
__ldexp_exp (generic function with 1 method)

julia> @code_llvm __ldexp_exp(0.245, -1)

; Function __ldexp_exp
; Location: REPL[31]:1
define double @julia___ldexp_exp_392966994(double, i64) {
top:
 %2 = call double inttoptr (i64 5074017824 to double (double, i64)*)(double %0, i64 %1)
 ret double %2
}

julia> @code_llvm __ldexp_exp_T(0.245, -1)

; Function __ldexp_exp_T
; Location: REPL[30]:1
define double @julia___ldexp_exp_T_392966995(double, i64) {
top:
 %gcframe = alloca %jl_value_t addrspace(10)*, i32 3
 %2 = bitcast %jl_value_t addrspace(10)** %gcframe to i8*
 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 24, i32 0, i1 false)
 %3 = call %jl_value_t*** inttoptr (i64 4546681056 to %jl_value_t*** ()*)() #3
 %4 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %gcframe, i32 0
 %5 = bitcast %jl_value_t addrspace(10)** %4 to i64*
 store i64 2, i64* %5
 %6 = getelementptr %jl_value_t**, %jl_value_t*** %3, i32 0
...
}

Hardcoding Int64 produces the same result as typeof(-1).

If I'm somehow breaking the rules of ccall I just don't know why. If it's a bug, I don't know what's happening either, so... 🤷‍♂️

Metadata

Metadata

Assignees

No one assigned

    Labels

    compiler:codegenGeneration of LLVM IR and native codeerror handlingHandling of exceptions by Julia or the user

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions