Skip to content

feat(VCR-ISA-001): extend generate-not-mirror Rocq ISA model to nine i64 pseudo-ops (41→50)#773

Merged
avrabe merged 2 commits into
mainfrom
feat/45-vcr-isa-extend2
Jul 15, 2026
Merged

feat(VCR-ISA-001): extend generate-not-mirror Rocq ISA model to nine i64 pseudo-ops (41→50)#773
avrabe merged 2 commits into
mainfrom
feat/45-vcr-isa-extend2

Conversation

@avrabe

@avrabe avrabe commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Wave-2 extension of the VCR-ISA-001 "generate, don't mirror" Rocq ISA model (#667 lineage, #242 epic): add the nine single-pseudo-op i64 register-pair shapes the selector already emits but were DSL-uncovered — 41 → 50 rules / Qed.

New ops (each a single flat-model pseudo-op with a fixed-register ancestor in CorrectnessI64.v, so the DSL work is pure register-generalization + re-export, exactly like i64.eqz #767):

family ops pseudo-op
unary bit counts i64.clz / i64.ctz / i64.popcnt I64{Clz,Ctz,Popcnt}Pseudo
binary pairs i64.mul / i64.shl / i64.shr_u / i64.shr_s I64{Mul,Shl,ShrU,ShrS}Pseudo
rotates i64.rotl / i64.rotr I64{Rotl,Rotr}Pseudo

Architecture (#667)

The shipped sel_dsl::RULES table EMITS VcrSelRulesGenerated.v (Module Gen) + generated.rs; VcrSelRules.v DEFINES rule_X := Gen.rule_X and states the 9 new correctness Qed directly about the generated sequences. A table change regenerates Gen and breaks the matching proof — drift is unrepresentable at the instruction-sequence level. Demonstrated: flipping Gen.rule_i64_mul from I64MulPseudo to I64ShlPseudo makes rule_i64_mul_correct fail to compile (//coq:rocq_proofs FAILED TO BUILD); reverted.

Side conditions (minimal, and correct)

Each pseudo-op reads every operand half into a local BEFORE any set_reg, so:

  • unary counts: none (rd may alias rn_lo — the R0,R0,R1 in-place emit is admitted);
  • binary pairs / rotates: a single rd_hi <> rd_lo (the high write must not destroy the low result word).

NOT the increment-3 three-condition pair set — those were flags-coupled ADDS+ADC pairs. Every select_with_stack emit site uses alloc_consecutive_pair, so rd_hi <> rd_lo holds by construction. Statements are value-level like the i64.eqz ancestor (no exec_wasm_instr hypothesis — the i64 ops aren't in WasmSemantics.v); shift/rotate count is the low half only (combine_i32 cnt I32.zero), matching the _bits_spec axioms.

Verification

  • Rocq green: bazel test //coq:verify_proofs//coq:rocq_proofs + //coq:vcr_sel_rules_coverage both PASS (all 50 rules, 50 Qed, 0 Admitted in the rule table).
  • Drift-guard: flipping a generated rule breaks its Qed (shown above).
  • Byte-invisibility: SYNTH_NO_SEL_DSL=1 vs default is bit-identical for these ops — mirror-pinned by sel_dsl_mirror_pin_i64_pair_rules_select_with_stack_242, extended with dedicated count/rotate/pair-bin probe windows (probed 16→25, each a byte-equality assert). The nine select_default blind arms are the holdout, unchanged (Delegation::SelectWithStack).
  • No regression: frozen anchors (cargo test -p synth-cli --test frozen_codegen_bytes) 10/10 intact; cargo test -p synth-synthesis --lib 624/624.
  • Claim gate: python3 scripts/claim_check.py claims.yaml19/19 hold (476→485 Qed, 41→50 rules, STATUS coverage 26%→32%).
  • fmt + clippy --workspace --all-targets -D warnings clean.

Refs #667 (VCR-ISA-001), #242. Do not merge without review.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L

avrabe and others added 2 commits July 16, 2026 00:19
…i64 pseudo-ops (41→50)

Wave-2 lane: add the single-pseudo-op i64 register-pair shapes the selector
already emits but were DSL-uncovered — i64.clz/ctz/popcnt (unary counts),
i64.mul/shl/shr_u/shr_s (binary pairs), and i64.rotl/rotr (rotates). Each is
ONE flat-model pseudo-op (I64{Clz,Ctz,Popcnt,Mul,Shl,ShrU,ShrS,Rotl,Rotr}Pseudo)
with a fixed-register ancestor in CorrectnessI64.v, so the DSL work is pure
register-generalization + re-export of the GENERATED Gen.rule_X — same pattern
as i64.eqz (#767) and the I64SetCond family.

Per the #667 architecture: the shipped sel_dsl::RULES table EMITS
VcrSelRulesGenerated.v (Module Gen) + generated.rs; VcrSelRules.v DEFINES
rule_X := Gen.rule_X and states the 9 new correctness Qed directly about the
generated sequences — a table change regenerates Gen and breaks the matching
proof (drift unrepresentable at the instruction-sequence level).

Side conditions are minimal because each pseudo-op reads every operand half
into a local BEFORE any set_reg: NONE for the unary counts (rd may alias
rn_lo — the R0,R0,R1 in-place emit is admitted); a SINGLE rd_hi <> rd_lo for
the pair/rotate shapes (the high write must not destroy the low result word).
NOT the increment-3 three-condition pair set (those were flags-coupled ADDS+ADC
pairs). Statements are value-level like the i64.eqz ancestor (no exec_wasm_instr
hypothesis — the i64 ops aren't in WasmSemantics); shift/rotate count is the
low half only (combine_i32 cnt I32.zero), matching the _bits_spec axioms.

New TemplateOp shapes: I64PairBin (mul/shl/shr), I64PairRot (rotl/rotr),
I64UnaryCount (clz/ctz/popcnt), with matching template_expr (Rust ArmOp) and
coq_instrs (Coq constructor) generator arms. Three dispatch fns
(i64_unary_count_rule / i64_pair_bin_rule / i64_rot_rule) wire the delegation
in select_with_stack (delegation SelectWithStack — select_default's blind arms
are the holdout, unchanged).

Byte-invisible: SYNTH_NO_SEL_DSL=1 vs default is bit-identical for these ops
(mirror-pinned by sel_dsl_mirror_pin_i64_pair_rules_select_with_stack_242,
extended with dedicated count/rotate/pair-bin probe windows; probed 16→25).
Every select_with_stack emit site uses alloc_consecutive_pair, so rd_hi<>rd_lo
holds by construction.

Rocq green: bazel test //coq:verify_proofs (rocq_proofs + vcr_sel_rules_coverage
both PASS). Manifest + coverage gates updated (41→50). Docs + claims.yaml in
follow-up commits.

Refs #667 (VCR-ISA-001 lineage), #242.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…-ops (41→50, 476→485)

Re-derive the CI-pinned counts after landing the nine wave-2 i64 rules:
- 476 → 485 Qed (README.md x3, CLAUDE.md, coq/STATUS.md headline + Total)
- 41 → 50 selector-DSL rules / Qed theorems (claims.yaml SYNTH-SEL-DSL-RULES
  + SYNTH-SEL-DSL-COVERAGE-STATUS-MD, README/CLAUDE prose)
- coq/STATUS.md per-op-family table: i64 mul (model-only → DSL-served),
  i64 shifts/rotates (5 → DSL-served), i64 bit-manip clz/ctz/popcnt (3 →
  DSL-served); DSL total 41→50 (26%→32%), model-only 95→86 (61%→55%);
  footnote 1 extended to the new pseudo-op-tier families.

Verified green: python3 scripts/claim_check.py claims.yaml -> 19/19 hold.

Refs #667 (VCR-ISA-001), #242.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.17978% with 17 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/synth-synthesis/src/instruction_selector.rs 95.40% 8 Missing ⚠️
crates/synth-synthesis/src/sel_dsl/generated.rs 95.62% 6 Missing ⚠️
crates/synth-synthesis/src/sel_dsl/mod.rs 97.76% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@avrabe
avrabe merged commit d618a93 into main Jul 15, 2026
38 checks passed
@avrabe
avrabe deleted the feat/45-vcr-isa-extend2 branch July 15, 2026 23:43
avrabe added a commit that referenced this pull request Jul 16, 2026
… WasmCert anchor + VCR-ISA 41→50, A64 7→50, 12× beat-LLVM, MC/DC provenance) (#775)

Five oracle-gated lanes across semantics/capability/perf/assurance:
- VCR-WASM-001 (#771): WasmCert-Coq source anchor (i32.add refinement, 474→476)
- VCR-ISA-001 (#773): generate-not-mirror 41→50 ops (476→485 Qed)
- #538 (#769): AArch64 milestone 2 — 7→50 integer ops, honest div/rem decline
- #494 (#770): proof-carrying rem_u elision — 12× beat over clang -Os
- #396 (#774): synth-provenance-v1 MC/DC source-to-object map (VCR-DEC-003)

#757 stays OPEN (accepted residual — 7 reconstructions all green, needs reporter
module; #772 lands them as regression guards). i64.trunc_f64 + #761 residuals noted.


Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant