Skip to content

VCR-RA-003: RV32 callee-saved / spill-slot allocation validator (RV32 analogue of the ARM-only liveness gate) #815

Description

@avrabe

Context

The VCR-RA-003 register-allocation validator (synth_synthesis::liveness::validate_final_allocation, #808) is ARM-only today. It runs unconditionally on every ARM compile and hard-errors on:

It is deeply coupled to the ARM backend:

  • signature is validate_final_allocation(instrs: &[ArmInstruction])
  • callee-saved set hard-coded [R4, R5, R6, R7, R8]
  • prologue/epilogue detected via ARM Push { regs } (LR-containing) / Pop
  • def/use classification via reg_effect(op: &ArmOp) (ArmOp-specific)

Why RV32 is a separate lane, not "also run it"

RV32 needs a parallel re-implementation, not a target parameter:

  • a different instruction enum (synth_backend_riscv::riscv_op::RiscVOp, not ArmInstruction)
  • a different callee-saved set — RV psABI s0s11 (x8x9, x18x27)
  • a different prologue/epilogue shape (addi sp, sp, -N + sw ra, …(sp), not a reg-list push)
  • no reg_effect def/use classifier exists for RiscVOp — one must be written (the RV analogue of the ARM reg_effect "bail-on-unmodeled → None" contract, so the fail-safe direction is preserved)

This was scoped honestly during the VCR-SEL-005 universe-complete cross-backend op-parity lane (#49): landing the parity gate solidly was preferred over half-implementing a soundness checker on a second backend.

Deliverable

  • validate_final_allocation_rv32(instrs: &[RiscVOp]) -> RaFinalVerdict (or a shared trait), with an RV32 reg_effect
  • red-first non-vacuity unit tests mirroring ra003_red_* / ra003_green_*: synthetically revert a known-fixed RV32 clobber → the validator CATCHES it; assert SILENT on correct RV32 codegen
  • wire it unconditionally on the RV32 compile path (mirroring the ARM wiring), frozen-safe (checker emits nothing — RV32 .text byte-identical, the frozen RV32 oracle unchanged)
  • a named CI job (sibling of vcr-ra-003-alloc-validator-gate)

Refs

Epic #242 (VCR-*). ARM validator: #808 / #490 / #331. Parity lane that scoped this out: #49.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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