Skip to content

feat: wide arithmetic proposal#306

Merged
guybedford merged 4 commits intomainfrom
wide-arithmetic
Mar 25, 2026
Merged

feat: wide arithmetic proposal#306
guybedford merged 4 commits intomainfrom
wide-arithmetic

Conversation

@logan-gatlin
Copy link
Copy Markdown
Contributor

Add support for the wide arithmetic proposal. Added 4 new instructions:

  • i64.add128
  • i64.sub128
  • i64.mul_wide_s
  • i64.mul_wide_u
    Enabled existing spec tests for the proposal. Bumped wasmprinter and wasmparser to versions which support wide arithmetic. I gated the new instructions behind only_stable_features = false since the prop is currently phase 3.

Copy link
Copy Markdown
Contributor

@guybedford guybedford left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: feat: wide arithmetic proposal

CI: All checks pass (stable, beta, nightly, fuzz, rustfmt)


Summary

This PR adds support for the Wide Arithmetic WebAssembly proposal (currently Phase 3), implementing four new instructions:

  • i64.add128 — 128-bit addition (4 × i64 → 2 × i64)
  • i64.sub128 — 128-bit subtraction (4 × i64 → 2 × i64)
  • i64.mul_wide_s — signed widening multiply (2 × i64 → 2 × i64)
  • i64.mul_wide_u — unsigned widening multiply (2 × i64 → 2 × i64)

Positive aspects

  • Clean, minimal implementation. The pattern matches exactly how prior instructions (e.g. AnyConvertExtern, ExternConvertAny) were added.
  • Feature-gated correctly. The proposal is Phase 3, and it's gated behind only_stable_features = false in config.rs. This is the right call.
  • Spec tests enabled. spec-tests.rs was updated from return Ok(()) (skip) to &[] (run with no expected failures), and the CI confirms they pass.
  • Round-trip test included. wide-arithmetic.wat covers all four instructions with a tidy CHECK-ALL snapshot.
  • All test snapshots updated. The mass-update to .wat snapshots is caused by the wasmprinter upgrade changing output ordering (exports before function bodies, @producers section now emitted). This is expected churn from the dep bump, not a logic change.

Issues and concerns

1. Doc comment describes operand order ambiguously for i64.add128 / i64.sub128

In src/ir/mod.rs:

/// Pops four i64 values (lo1, hi1, lo2, hi2), computes (lo1:hi1) + (lo2:hi2)

The spec uses lhs_lo, lhs_hi, rhs_lo, rhs_hi terminology — naming them lo1/hi1/lo2/hi2 makes it unclear which value is the low vs high half of each operand. A small wording fix would improve clarity for future readers.

2. Confirm exhaustive match coverage

The is_barrier() method was correctly updated, but walrus has other sites that match on Instr (passes, analysis, dot graph, etc.). Since the compiler enforces exhaustiveness these should all be caught at compile time — but any _ => {} catch-alls would silently swallow the new variants. Worth a quick audit to confirm no silent gaps.

3. wasmprinter version bump drops a pinned exact version (0.2.78 → 0.245)

The old "=0.2.78" pin suggests there was a deliberate reason for it at some point. Worth confirming that dropping the pin doesn't reintroduce whatever caused it to be pinned originally.

4. wasmparser bump is only in fuzz-utils, not the root crate

fuzz-utils/Cargo.toml bumps wasmparser from 0.212 to 0.245, but the root crate's dependency doesn't appear in the diff. CI passes so this is presumably fine, but it's worth explicitly noting that the Operator::I64Add128 etc. variants come from the root crate's wasmparser version.

5. Minor: loop2.wat snapshot change

The change from br_if 1 (;@0;) to br_if 1 (dropping the inline label comment) is a cosmetic output change from the wasmprinter upgrade, not a semantic change. Fine, but worth calling out so it isn't mistaken for a logic regression.


Verdict

The core implementation is correct and follows established patterns in the codebase. CI is fully green. The main items above are minor — the doc comment clarity and confirming the wasmprinter pin drop are the most worth addressing before merge. Overall this is a solid Phase 3 proposal integration.

@logan-gatlin
Copy link
Copy Markdown
Contributor Author

logan-gatlin commented Mar 25, 2026

  1. Docs are fixed.
  2. Three other catch-alls checked, two in traversals.rs and one in local_function/emit.rs. Both are correct.
  3. The wasmprinter pin was there presumably to prevent minor changes from messing up the snapshot output (like what happened when I bumped the version). Keeping the old version is not an option because it does not support wide arithmetic.
  4. Version bump is not in the diff because the version was already bumped on main.
  5. No action needed

The previous pinned wasmprinter (0.2.78) did not support wide arithmetic
opcodes. Upgrade to 0.245 which supports all current proposals and
regenerate round-trip test CHECK patterns to match the new printer output
format (section reordering, symbolic type names).
@guybedford guybedford merged commit f5f5d9f into main Mar 25, 2026
18 checks passed
@guybedford guybedford deleted the wide-arithmetic branch March 25, 2026 22:16
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.

2 participants