Skip to content

Direct selector miscompiles value-returning br_table — carried value dropped (affects --relocatable/shipped path) #509

Description

@avrabe

Summary

The direct instruction selector (select_with_stack) silently miscompiles a value-returning br_table: when a br (from a br_table arm) targets a block with a result type and carries a value, the carried value is dropped — the dispatched arms return 0 instead of their value. Only the default/fall-through arm is correct.

This is distinct from #507 (which is the optimized path dropping the dispatch for void br_table; fixed by declining to direct). This bug is in the direct selector itself, so it affects both --relocatable and --no-optimize — i.e. the shipped path (gust/falcon use --relocatable). Surfaced while gating the #507 fix: declining the optimized path to the direct selector exposed that the direct selector is also wrong for this shape.

Silent wrong-code, exit 0 — an #180/#185 Ok-or-Err violation on the shipped path.

Minimal repro

btval.wat:

(module
 (func (export "pick") (param i32) (result i32)
  (block $end (result i32)
   (block $c2
    (block $c1
     (block $c0
      (br_table $c0 $c1 $c2 (local.get 0)))
     (br $end (i32.const 10)))
    (br $end (i32.const 20)))
   (i32.const 30))))

Oracle (wasmtime): pick(0..2)10, 20, 30; pick(≥2)30.

synth (BOTH --relocatable and default→direct), executed under unicorn:

pick(0) = 0   (expect 10)   <-- carried value dropped
pick(1) = 0   (expect 20)   <-- carried value dropped
pick(2) = 30  (expect 30)   OK (default arm)

The br_table dispatch itself is correct (cases 0/1 don't fall to default), but br $end (value) doesn't deliver the value — r0 is 0 at return for the dispatched arms.

Scope / impact

Likely cause

The operand-stack tracking across a br that carries a block result — the value pushed before br $end isn't materialized into the result register on the branch edge. Same family as the #313 if/else result-reconciliation machinery, but for br-to-labeled-block-with-result.

Repro files on request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions