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

On "llvmcall with integer pointers is deprecated, use an actual pointer type instead." on nightly #53916

Closed
sumiya11 opened this issue Apr 2, 2024 · 3 comments

Comments

@sumiya11
Copy link
Contributor

sumiya11 commented Apr 2, 2024

#53687 seems to have introduced this warning recently to promote the use of i8* and ptr instead of i64 for pointers in llvmcall .

Curiously, the use of i8* over i64 seems to have an impact on the actual generated code (on 1.10.2). Consider the two functions:
 

@generated function foo_old(a::Vector{UInt32})  # same as `@inbounds a[1]`
    textir = """
    define i32 @entry(i64 %0) #0 {
        %arr = inttoptr i64 %0 to i32*
        %arr.i = getelementptr inbounds i32, i32* %arr, i64 0
        %x = load i32, i32* %arr.i, align 4
        ret i32 %x
    }
    attributes #0 = { alwaysinline }
    """
    quote
        GC.@preserve a begin
            Base.llvmcall(($textir, "entry"), UInt32, Tuple{Ptr{UInt32}}, pointer(a))
        end
    end
end

@generated function foo_new(a::Vector{UInt32})
    textir = """
    define i32 @entry(i8* %0) #0 {
        %arr = bitcast i8* %0 to i32*
        %arr.i = getelementptr inbounds i32, i32* %arr, i64 0
        %x = load i32, i32* %arr.i, align 4
        ret i32 %x
    }
    attributes #0 = { alwaysinline }
    """
    quote
        GC.@preserve a begin
            Base.llvmcall(($textir, "entry"), UInt32, Tuple{Ptr{UInt32}}, pointer(a))
        end
    end
end

The IR of foo_new reported by @code_llvm has an additional call:

@code_llvm debuginfo = :none foo_old([UInt32(1)])
; Function Attrs: uwtable
define i32 @julia_foo_old_2191({}* noundef nonnull align 16 dereferenceable(40) %0) #0 {
top:
  %1 = bitcast {}* %0 to i32**
  %arrayptr2 = load i32*, i32** %1, align 8
  %x.i = load i32, i32* %arrayptr2, align 4
  ret i32 %x.i
}

@code_llvm debuginfo = :none foo_new([UInt32(1)])
; Function Attrs: uwtable
define i32 @julia_foo_new_2194({}* noundef nonnull align 16 dereferenceable(40) %0) #0 {
top:
  %1 = bitcast {}* %0 to i8**
  %arrayptr2 = load i8*, i8** %1, align 8
  %2 = call i32 @julia_foo_new_2194u2196(i8* nonnull %arrayptr2)
  ret i32 %2
}

The assembly reported by @code_native differs as well.
The extra nanosecond here "confirms" that there is some difference:

@btime foo_old($([UInt32(9)]));
  2.600 ns (0 allocations: 0 bytes)

@btime foo_new($([UInt32(9)]));
  3.800 ns (0 allocations: 0 bytes)

I wonder if this is expected ?

On master e9d25ca , foo_old and foo_new are identical.

julia> versioninfo()
Julia Version 1.10.2
Commit bd47eca2c8 (2024-03-01 10:14 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 8 × Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, skylake)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)
Environment:
  JULIA_EDITOR = code
  JULIA_NUM_THREADS = 4
@oscardssmith
Copy link
Member

I'm not sure if it is "expected", but I don't think it's a problem. LLVM gets breaking changes pretty much every Julia version, and the details of how lowering of Julia code to LLVM happens (or even that LLVM exists in the compile pipeline) aren't part of the stable interface.

@maleadt
Copy link
Member

maleadt commented Apr 2, 2024

the use of i8* over i64 seems to have an impact on the actual generated code (on 1.10.2).

llvmcall with actual pointer types is only supported on 1.12. On an assertions build, this would probably abort.

@maleadt
Copy link
Member

maleadt commented Apr 3, 2024

julia> versioninfo()
Julia Version 1.10.2

julia> foo_new([UInt32(1)])
julia: /source/src/ccall.cpp:967: jl_cgval_t emit_llvmcall(jl_codectx_t&, jl_value_t**, size_t): Assertion `*it == f->getFunctionType()->getParamType(i)' failed.

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

3 participants