Skip to content

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

@avrabe

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
    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