Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in compiling llvmcall with tuple argument for declarations and IR. #26297

Closed
vchuravy opened this issue Mar 2, 2018 · 4 comments
Closed

Comments

@vchuravy
Copy link
Member

vchuravy commented Mar 2, 2018

Probably related to linear IR and #25041, but since we actually have tests for it

julia/test/llvmcall.jl

Lines 127 to 134 in df489f0

function ceilfloor(x::Float64)
llvmcall(
("""declare double @llvm.ceil.f64(double)
declare double @llvm.floor.f64(double)""",
"""%2 = call double @llvm.ceil.f64(double %0)
%3 = call double @llvm.floor.f64(double %2)
ret double %3"""),
Float64, Tuple{Float64}, x)

I was surprised recently by triggering this in the REPL and when loading code with -L.

julia> f(x::Int64) = Base.llvmcall(("", "ret i64 %0"), Int64, Tuple{Int64}, x)
julia> f(1)
ERROR: error compiling f:

julia> @code_typed f(1)
CodeInfo(:(begin
      Core.SSAValue(1) = (Core.tuple)("", "ret i64 %0")::Tuple{String,String}
      Core.SSAValue(3) = (llvmcall)(Core.SSAValue(1), Main.Int64, Tuple{Int64}, x)::Int64
      return Core.SSAValue(3)
  end)) => Int64

This can be worked around by using a @generated function

@generated function g(x::Int64)
          decl = ""
          ir = "ret i64 %0"
          quote
             Base.llvmcall($(decl, ir), Int64, Tuple{Int64}, x)
          end
       end

julia> @code_typed g(1)
CodeInfo(:(begin
      #= REPL[11]:2 =#
      # meta: location REPL[11] @generated body
      #= line 5 =#
      Core.SSAValue(2) = (llvmcall)(("", "ret i64 %0"), Main.Int64, Tuple{Int64}, x)::Int64
      return Core.SSAValue(2)
      # meta: pop location
  end)) => Int64

cc: @quinnj

@jmert
Copy link
Contributor

jmert commented Mar 7, 2018

I came across this for cglobal as well. I was being impatient and seeing if I could get PyPlot up and running on master, but PyCall fails to compile due to this same problem.

MWE:

module Test1
    const libpython = "/usr/lib/libpython3.6m"

    struct OpaqueStruct end

    macro pyglobalobj1(name)
        :(cglobal(($(esc(name)), libpython), OpaqueStruct))
    end

    macro pyglobalobj2(name)
        :(cglobal(($(esc(name)), $libpython), OpaqueStruct))
    end

    f1() = @pyglobalobj1(:PyRange_Type)
    f2() = @pyglobalobj2(:PyRange_Type)
end

@code_typed Test1.f1()
@code_typed Test1.f2()

Test1.f1()
Test1.f2()

On master:

julia> @code_typed Test1.f1()
CodeInfo(:(begin
      Core.SSAValue(0) = (Core.tuple)(:PyRange_Type, Main.Test1.libpython)::Tuple{Symbol,String}
      Core.SSAValue(1) = (Main.Test1.cglobal)(Core.SSAValue(0), Main.Test1.OpaqueStruct)::Ptr{Main.Test1.OpaqueStruct}
      return Core.SSAValue(1)
  end)) => Ptr{Main.Test1.OpaqueStruct}

julia> @code_typed Test1.f2()
CodeInfo(:(begin
      Core.SSAValue(0) = (Core.tuple)(:PyRange_Type, "/usr/lib/libpython3.6m")::Tuple{Symbol,String}
      Core.SSAValue(1) = (Main.Test1.cglobal)(Core.SSAValue(0), Main.Test1.OpaqueStruct)::Ptr{Main.Test1.OpaqueStruct}
      return Core.SSAValue(1)
  end)) => Ptr{Main.Test1.OpaqueStruct}

julia> Test1.f1()
ERROR: TypeError: in f1, in cglobal: first argument not a pointer or valid constant expression, expected Ptr, got Tuple{Symbol,String}
Stacktrace:
 [1] f1() at ./REPL[43]:14
 [2] top-level scope

julia> Test1.f2()
ERROR: TypeError: in f2, in cglobal: first argument not a pointer or valid constant expression, expected Ptr, got Tuple{Symbol,String}
Stacktrace:
 [1] f2() at ./REPL[43]:15
 [2] top-level scope

On v0.6.2:

julia> @code_typed Test1.f1()
CodeInfo(:(begin 
        return (Test1.cglobal)((Core.tuple)(:PyRange_Type, Test1.libpython)::Tuple{Symbol,String}, Test1.OpaqueStruct)::Ptr{Test1.OpaqueStruct}
    end))=>Ptr{Test1.OpaqueStruct}

julia> @code_typed Test1.f2()
CodeInfo(:(begin 
        return (Test1.cglobal)((Core.tuple)(:PyRange_Type, "/usr/lib/libpython3.6m")::Tuple{Symbol,String}, Test1.OpaqueStruct)::Ptr{Test1.OpaqueStruct}
    end))=>Ptr{Test1.OpaqueStruct}

julia> Test1.f1()
Ptr{Test1.OpaqueStruct} @0x00007f1fb13a0460

julia> Test1.f2()
Ptr{Test1.OpaqueStruct} @0x00007f1fb13a0460

@chethega
Copy link
Contributor

FWIW, the following works around the bug:

julia> using Base: llvmcall
julia> f(x::Int64) = llvmcall(("", "ret i64 %0"), Int64, Tuple{Int64}, x)
f (generic function with 1 method)
julia> f(1)
1

tkoolen added a commit to tkoolen/FunctionWrappers.jl that referenced this issue Jul 9, 2018
Mostly straightforward, but note that (probably due to JuliaLang/julia#26297), llvmcall has to be imported from Base in order to avoid the error 'error compiling assume: error statically evaluating llvm IR argument'. Also note that cfunction calls have been replaced with ccalls to jl_function_ptr, while they should probably be replaced with cfunction macro calls. The problem is however that the cfunction macro expects a literal tuple for the argument types.
@tkoolen
Copy link
Contributor

tkoolen commented Jul 9, 2018

I also ran into this issue with FunctionWrappers. @chethega's workaround worked there as well (unfortunately I didn't find this issue initially and trial-and-errored my way to the same solution).

Here's the error message from FunctionWrappers for better searchability:

ERROR: error compiling assume: error statically evaluating llvm IR argument

@tkoolen
Copy link
Contributor

tkoolen commented Jul 20, 2018

#28172 fixed the FunctionWrappers error, as well as the example in the issue description. Close?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants