Skip to content

Resolve small type tags when looking up referenced objects - #961

Merged
maleadt merged 1 commit into
tb/reject-reference-allocationsfrom
tb/small-type-tags
Sep 28, 2026
Merged

maleadt merged 1 commit into
tb/reject-reference-allocationsfrom
tb/small-type-tags

Conversation

@maleadt

@maleadt maleadt commented Sep 25, 2026

Copy link
Copy Markdown
Member

Fixes the crash reported on #949; meant to be folded into that PR.

Since Julia 1.10, codegen refers to some types by a small tag rather than their address: an offset into jl_small_typeof, below jl_max_tags << 4. On 1.12+, Core.svec is allocated inline with such a tag as the type operand:

call ptr @julia.gc_alloc_obj(ptr %current_task, i64 16, ptr inttoptr (i64 144 to ptr))

check_allocation! passes that operand to referenced_object, which treated every inttoptr constant as an object address, so compiling a kernel like this segfaulted:

using Metal
k(a) = (Base.donotdelete(Core.svec(a[1])); nothing)
Metal.code_llvm(devnull, k, Tuple{MtlDeviceVector{Float32,1}}; kernel = true)

referenced_object now looks up constants below jl_max_tags << 4 in jl_small_typeof, as jl_to_typeof does. Unused table entries and non-constant inttoptr operands are treated as unknown. Larger constants are still treated as object addresses, as before: 1.10's codegen and :bake relocations embed them. The svec allocation above is now reported as unsupported allocation of an object with references (Core.SimpleVector).

Tests: the Metal unsupported allocations testset has a kernel that allocates an svec, checked on 1.12+ because older versions call jl_f_svec instead. It also calls referenced_object directly, on every version, for a small tag, an unused tag and a type address. Without the fix, the test worker segfaults. I ran the Metal tests on 1.10 through 1.13, the SPIR-V tests on the same versions, and the full suite on 1.10 and 1.12. PTX and GCN tests were skipped because those back-ends aren't available on macOS. With Metal.jl 1.11.1, the reproducer above no longer crashes, and launching the kernel with @metal raises the InvalidIRError.

Julia 1.10+ refers to some types by a small tag instead of their
address: an offset into `jl_small_typeof`, below `jl_max_tags << 4`.
Codegen emits such a tag as the type operand of `julia.gc_alloc_obj`,
e.g., since 1.12 when allocating a `Core.svec` inline, where
`check_allocation!` passed it to `referenced_object`. That treated
every `inttoptr` constant as an object address and dereferenced the
tag, crashing the compiler.

Look small tags up in `jl_small_typeof` instead, as `jl_to_typeof`
does, and treat unused table entries and non-constant operands as
unknown. Larger constants are still object addresses, as embedded by
1.10's codegen or by baking relocations. Such allocations of a
`SimpleVector` are now reported as allocations of an object with
references.
@codecov

codecov Bot commented Sep 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.56%. Comparing base (89ef241) to head (c019afb).

Additional details and impacted files
@@                         Coverage Diff                         @@
##           tb/reject-reference-allocations     #961      +/-   ##
===================================================================
+ Coverage                            86.39%   86.56%   +0.17%     
===================================================================
  Files                                   29       29              
  Lines                                 5805     5813       +8     
===================================================================
+ Hits                                  5015     5032      +17     
+ Misses                                 790      781       -9     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@maleadt
maleadt merged commit 634b0b2 into tb/reject-reference-allocations Sep 28, 2026
32 of 33 checks passed
@maleadt
maleadt deleted the tb/small-type-tags branch September 28, 2026 06:45
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