Skip to content

rv32: if/else-with-result lowering has no result-register reconciliation (same class as #313) #343

@avrabe

Description

@avrabe

[synth-side issue-hunt loop — maintainer voice, NOT gale]
Found while fixing the ARM analogue (#313).

The RISC-V selector has the same if/else-with-result reconciliation gap that #313 fixes on ARM. In `crates/synth-backend-riscv/src/selector.rs`, `lower_else` (~line 1626) truncates the then-arm's results off the vstack (`vstack.truncate(frame.stack_height_at_entry)`) but neither captures them nor reconciles at `lower_end` (~line 1655). So an `if (result …)` returns the else-arm's register on the then path — same silent wrong-code class as #313, arguably worse (it discards the then-results rather than leaving them stacked).

Fix: mirror the #313 ARM fix — at `lower_else` capture the then-arm result registers (instead of just truncating) and reserve them across the else-arm; at `lower_end` reconcile (`mv rd_then, rd_else` on the else path) onto a single register, skipping the `mv` when the arms already agree (byte-identity on symmetric cases).

Repro shape (the RV32 analogue of #313's): `(if (result i32) (then ) (else (i32.const …)))` compiled `-b riscv --target rv32imac`. Severity: silent wrong-code; no known production hit yet (gale's RV32 seams haven't exercised an asymmetric if-result). Should ride ahead of RV32 perf work, same as #313 did on ARM.

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