Skip to content

codegen: cast globals to the generic address space where used as pointers - #63715

Merged
DilumAluthge merged 1 commit into
JuliaLang:masterfrom
maleadt:tb/global-addrspace-casts
Oct 10, 2026
Merged

DilumAluthge merged 1 commit into
JuliaLang:masterfrom
maleadt:tb/global-addrspace-casts

Conversation

@maleadt

@maleadt maleadt commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

LLVM creates globals in the datalayout's globals address space. On AMDGPU and SPIR-V this is address space 1, but several codegen paths use their addresses where a generic ptr is required. Runtime symbol lookup passes the library-handle global to jl_load_and_lookup without a cast; union typeof bitcasts type slots across address spaces or selects a small-tag global against a generic null; and @cfunction uses globals as runtime call arguments and elements of a generic-pointer initializer. The resulting IR fails verification with Invalid bitcast or Call parameter type does not match function signature!.

This causes the verifier abort described in JuliaGPU/AMDGPU.jl#1149, for which JuliaGPU/GPUCompiler.jl#1003 adds a runtime-lookup workaround. The union typeof paths also affect ordinary device code, such as selecting between Int32 and Float32 values and comparing the selected value's type.

Add generic_global_ptr, using ConstantExpr::getPointerBitCastOrAddrSpaceCast, at uses that require a generic pointer. It also replaces the existing casts for string constants and small-type slots. Casting at each use preserves direct loads and stores in the global's address space, which permits better AMDGPU code than casting every global at creation. Globals already in address space 0 are unchanged, and emission_context.cfuncs continues to retain the raw GlobalVariable.

This follows Clang's treatment of globals whose storage address space differs from the pointer address space expected by the language: CodeGenModule::GetOrCreateLLVMGlobal returns an address-space cast in that case. Julia applies the cast at the uses that require a generic pointer, rather than returning a cast when the global is created, so direct memory accesses retain the storage address space.

Validated with GPUCompiler main (6783e66) and LLVM.jl 10.1.0, using separate depots for the baseline nightly (1.14.0-DEV.3501, f5fdd1cdc80) and the assertions-enabled fixed build (1.14.0-DEV.3587, based on 3d57df8728). These are different Julia revisions. check.jl verifies raw output from GPUCompiler.compile_method_instance on GCN and SPIR-V (backend=:llvm for SPIR-V). The fixed results are identical with and without CI=true:

Raw IR case Before, GCN / SPIR-V After, GCN / SPIR-V
tag: union typeof comparison Invalid bitcast / Invalid bitcast Verifies / Verifies
tag2: three-way union typeof Invalid bitcast / Invalid bitcast Verifies / Verifies
smalltag: union isa Verifies / Verifies Verifies / Verifies
alloc_string: runtime ccall lookup Call parameter mismatch / Call parameter mismatch Verifies / Verifies
cfun: closure @cfunction Call parameter mismatch / Call parameter mismatch Verifies / Verifies
cfun_static: static @cfunction Call parameter mismatch / Call parameter mismatch Verifies / Verifies
GCN end-to-end case Before After, with and without CI=true
Union typeof kernel Unresolved cglobal load after relocation lowering Same GPUCompiler relocation failure; LLVM IR verifies
alloc_string InvalidIRError InvalidIRError, without a verifier abort

The remaining kernel failure is a GPUCompiler follow-up.

Assisted by: Sol 6.1

…ters

Globals can live in a nonzero address space on targets such as AMDGPU and
SPIR-V. Cast their addresses at generic pointer uses in runtime symbol
lookup, union typeof, and `@cfunction` codegen so the emitted IR verifies.
Keep direct loads and stores in the globals' address space.

Assisted-by: Codex (GPT-6)
@maleadt maleadt added compiler:codegen Generation of LLVM IR and native code gpu Affects running Julia on a GPU backport 1.13 Change should be backported to release-1.13 labels Oct 10, 2026
@maleadt maleadt added the merge me PR is reviewed. When all tests are passing merge, making sure commit message is good. label Oct 10, 2026
@DilumAluthge
DilumAluthge merged commit 73bc166 into JuliaLang:master Oct 10, 2026
12 of 13 checks passed
@DilumAluthge DilumAluthge removed the merge me PR is reviewed. When all tests are passing merge, making sure commit message is good. label Oct 10, 2026
@KristofferC KristofferC mentioned this pull request Oct 20, 2026
15 of 29 tasks
KristofferC pushed a commit that referenced this pull request Oct 20, 2026
…ters (#63715)

Globals can live in a nonzero address space on targets such as AMDGPU and
SPIR-V. Cast their addresses at generic pointer uses in runtime symbol
lookup, union typeof, and `@cfunction` codegen so the emitted IR verifies.
Keep direct loads and stores in the globals' address space.

Assisted-by: Codex (GPT-6)
(cherry picked from commit 73bc166)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport 1.13 Change should be backported to release-1.13 compiler:codegen Generation of LLVM IR and native code gpu Affects running Julia on a GPU

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants