Skip to content

ccall in the llvmcall convention - #23

Draft
vchuravy wants to merge 1 commit into
vc/jc-21-globalsfrom
vc/jc-22-llvmcall-cc
Draft

vchuravy wants to merge 1 commit into
vc/jc-21-globalsfrom
vc/jc-22-llvmcall-cc

Conversation

@vchuravy

Copy link
Copy Markdown
Contributor

Stacked on #22. GPUCompiler's suite with codegen=:juliacodegen found this gap: GPU code calls its intrinsics with ccall("llvm.nvvm…", llvmcall, …), and JuliaCodegen rejected the llvmcall convention.

emit_llvmcall_cc calls the LLVM function name, as native code does:

  • Declaration: the function is declared with llvmcall's LLVM types (tuples of VecElements become vectors, other structs stay structs), or reused if the module already declares it with the same type.
  • Values: arguments and results whose LLVM type differs are reinterpreted.
  • Unknown intrinsics: an intrinsic LLVM doesn't know (llvm.nvvm.nonexistent) is declared too, so back ends and GPUCompiler's validation report it ("unknown intrinsic").

These throw Unsupported:

  • non-intrinsic names, which native code compiles to an error;
  • unmangled overloaded intrinsics, whose names native code mangles from the signature;
  • variadic calls.

Tests (test/ccall.jl): differential runs of llvm.sqrt.f64, llvm.ctpop.i64, the vector llvm.fma.v4f32 and the void llvm.donothing; FileCheck of the call and of the unknown intrinsic's declaration; and a non-intrinsic name.

The full suite passes locally on 1.12 and nightly (5950 and 5955 tests).

🤖 Generated with Claude Code

`ccall("llvm.name", llvmcall, rt, argtypes, args...)` calls the LLVM function
`name`, as native code does. GPU code uses it for its intrinsics, e.g. CUDA's
thread indices.

- The function is declared with `llvmcall`'s LLVM types (tuples of
  `VecElement`s are vectors, other structs are structs), or reused if the
  module declares it with the same type.
- Arguments and results whose LLVM type differs are reinterpreted.
- An intrinsic LLVM doesn't know is declared as well, for back ends and
  GPUCompiler's validation to report.

These throw `Unsupported`: non-intrinsic names (native code compiles them to an
error), unmangled overloaded intrinsics (whose names native code mangles from
the signature), and variadic calls.

Assisted-by: Claude Code (Opus 5.5)
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

Successfully merging this pull request may close these issues.

1 participant