Stream: git-wasmtime

Topic: wasmtime / issue #14569 Cranelift: inliner remaps dynamic...


view this post on Zulip Wasmtime GitHub notifications bot (Oct 06 2026 at 15:04):

fitzgen commented on issue #14569:

<details><summary>Full LLM report</summary>

Cranelift inliner gives inlined dynamic stack slots the wrong dynamic type

Date 2026-10-05
Wasmtime commit 73b04cff3317d1e308866eb24359483ac6116669 (main)
Host macOS 15.8.1 (Darwin 24.6.0), aarch64-apple-darwin
Model Claude Opus 5.5 (claude-opus-5-5)
Component cranelift/codegen/src/inline.rs (create_dynamic_types)
Class Wrong entity remapping: compile panic, or a silently wrong slot type
Severity Low. Wasmtime never emits dynamic types; this affects Cranelift embedders that use Context::inline with dynamic vectors.

Summary

create_dynamic_types (cranelift/codegen/src/inline.rs:1559-1565) computes
the offset that it adds to every callee DynamicType index from the wrong
table:

fn create_dynamic_types(func: &mut ir::Function, callee: &ir::Function, ...) -> u32 {
    let offset = func.dynamic_stack_slots.len();   // should be func.dfg.dynamic_types.len()
    ...
    for ... in callee.dfg.dynamic_types.values() {
        func.dfg.dynamic_types.push(...);          // appended at dynamic_types.len()

The callee's dynamic types are appended at func.dfg.dynamic_types.len(). But
create_dynamic_stack_slots and every inlined instruction that names a
dynamic type remap the index using the dynamic-stack-slot count. When the
caller has a different number of dynamic stack slots than dynamic types, every
inlined reference names the wrong dtN, and the verifier accepts it:

This has been present since the inliner landed (968952abe5, #11210). The
existing cranelift/filetests/filetests/inline/dynamic-stack-slots.clif misses
it because its caller has equal numbers of slots and types.

Reproduction

Run from the repository root.

$ target/debug/clif-util test reports/018-inline-dynamic-type-offset/repro-inline.clif
    Missed #0: \bdss2 = explicit_dynamic_slot dt1\b       # caller: 1 type, 2 slots
Error: 1 failure

$ target/debug/clif-util test reports/018-inline-dynamic-type-offset/repro-wrong-type.clif
    Missed #0: \bdss1 = explicit_dynamic_slot dt2\b       # caller: 2 types, 1 slot
Error: 1 failure                                          # (gets the caller's i8x16 dt1)

$ cargo run --manifest-path reports/018-inline-dynamic-type-offset/harness/Cargo.toml -- \
      reports/018-inline-dynamic-type-offset/repro.clif
verifier OK for %caller
thread 'main' panicked at cranelift/codegen/src/ir/function.rs:276:32:
Undeclared dynamic vector type: dt2

harness/ is a roughly 60-line program that drives Cranelift's public API on
a .clif file:

  1. Parse the file with cranelift-reader.
  2. Inline every call with Context::inline.
  3. Run the verifier.
  4. Context::compile for aarch64, then print the relocations.

Suggested fix

Use func.dfg.dynamic_types.len() for the offset. Add test inline filetests
whose caller has unequal numbers of dynamic types and dynamic stack slots, in
both directions.

Separately, the verifier should check that each dynamic stack slot's dyn_ty
is declared, so that this class of bug fails verification instead of panicking
in the ABI code.

</details>

view this post on Zulip Wasmtime GitHub notifications bot (Oct 06 2026 at 15:05):

fitzgen opened issue #14569:

create_dynamic_types in cranelift/codegen/src/inline.rs computes its
offset from func.dynamic_stack_slots.len(), but it should use
func.dfg.dynamic_types.len(). Whenever the caller has a different number
of dynamic stack slots than dynamic types, inlined slots name the wrong
dynamic type. The verifier accepts the result, and then:

.clif Test Case

test inline
target aarch64

function %callee(i32) {
    gv0 = dyn_scale_target_const.i32x4
    dt0 = i32x4*gv0
    dss0 = explicit_dynamic_slot dt0
block0(v0: i32):
    v1 = splat.dt0 v0
    v2 = dynamic_stack_addr.i64 dss0
    store.dt0 notrap aligned v1, v2
    return
}

function %caller() {
    gv0 = dyn_scale_target_const.i64x2
    dt0 = i64x2*gv0
    dss0 = explicit_dynamic_slot dt0
    dss1 = explicit_dynamic_slot dt0
    fn0 = %callee(i32)
block0:
    v0 = iconst.i32 1
    call fn0(v0)
    return
}
; check: dss2 = explicit_dynamic_slot dt1

Steps to Reproduce

clif-util test test.clif

Expected Results

The inlined slot uses the copied callee type:
dss2 = explicit_dynamic_slot dt1.

Actual Results

    Missed #0: \bdss2 = explicit_dynamic_slot dt1\b
    >     dss2 = explicit_dynamic_slot dt2

The caller has no dt2. Compiling the inlined function panics with
Undeclared dynamic vector type: dt2.

Versions and Environment

Cranelift version or commit: 73b04cff33

Operating system: macOS 15.8.1

Architecture: aarch64

view this post on Zulip Wasmtime GitHub notifications bot (Oct 06 2026 at 15:05):

fitzgen added the bug label to Issue #14569.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 06 2026 at 15:05):

fitzgen added the cranelift label to Issue #14569.


Last updated: Oct 11 2026 at 04:10 UTC