Skip to content

rv32: i64.div_s/rem_s sign computation clobbered by the udiv core's fixed registers — wrong signs (pre-existing) #317

Description

@avrabe

Found while verifying #312 (PR #316) with the new RV32 behavioral oracle — strictly pre-existing: the probe doesn't even execute on the parent commit (UC_ERR_INSN_INVALID), and 6/6 vectors fail post-#312 with wrong signs.

Root cause: the i64 signed-division lowering allocates nsign/dsign temporaries, which land in t4/t5 — the udiv core's fixed DIV_D_LO/HI registers. The core's input parallel-move overwrites them before result_sign = nsign ^ dsign is computed, so e.g. divs(-100,3) = 0x1f where wasmtime says 0xffffffdf. The same fixed-register file (T0-T6/S1-S3) clobbers any live vstack value sitting there across an i64 div — the #312 per-op pin scope protects within an op but the div core's fixed file bypasses the allocator entirely.

Fix directions: (a) move the sign temporaries to S4-S6 (outside the core's fixed file), or (b) make the div core spill/restore around live values, or (c) give the core allocator-chosen registers. (a) is the bounded v1.

Evidence staged: /tmp/i64_divs.wat + /tmp/i64_divs_diff.py (6-vector unicorn-vs-wasmtime probe) — will commit as scripts/repro/ lane with the fix.

Same family as #232 (constants into the live numerator) and the #312 aliasing — all symptoms of fixed/blind register choices in hand-written lowerings; the structural cure is the VCR program (#242), this is the containment fix. Queue: after v0.11.37 tags (it's not a regression and the u64-decide pattern doesn't divide).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions