Files
wasm2go/testdata/cg_negzero_flows.wat
263df3adca ssa: accept bool-typed br_table selectors (#29)
* ssa: accept bool-typed br_table selectors

wasm comparisons leave i32 0/1 on the stack and a br_table may select
on one directly — SpiderMonkey's with-Intl build does (its Fn7964),
which made the whole engine untranslatable: the SSA verifier rejected
the selector because wasm2go types comparison results as TypeBool.

The emitter always materializes bool values through b2i32, so a bool
selector already emits as a plain i32 switch operand; accepting the
type in the verifier is the entire fix. New fixture cg_brtable_bool.wat
reproduces the exact failure (differential against wazero: selector 0/1
routes to the right arm) and passes after; go test ./... exit 0.

Co-Authored-By: Claude Fable 5 <[email protected]>

* codegen: add negative-zero flow fixture (locals/phi/select/copysign/load)

Documents that every tested -0 flow shape emits correctly in the pure
backend: through locals, block results, phi merges, select, copysign
with constant magnitude or sign, f64.neg, data-segment loads, and
arithmetic. All shapes build the -0 inside wasm (the fixture harness's
synthesized main passes f64 args as decimal literals, so raw-bit f64
arguments cannot be used in fixtures).

The remaining -0 e2e failures against the translated SpiderMonkey are
engine-code-shape dependent (same translator: the without-intl engine
loses -0 in Math.sumPrecise / gcasm atan2 while the with-intl engine
passes), so they live in shapes not yet captured here.

Co-Authored-By: Claude Fable 5 <[email protected]>

---------

Co-authored-by: Claude Fable 5 <[email protected]>
2026-07-12 14:34:59 +09:00

39 lines
1.8 KiB
WebAssembly Text Format

;; cg_negzero_flows.wat — negative zero flowing through non-constant shapes:
;; locals, block results, phi merges, select, and a data segment. Hunts the
;; path that still loses -0 in SpiderMonkey's Math.sumPrecise after the
;; f64.const fix (observed on BOTH backends).
(module
(memory (export "memory") 1)
(data (i32.const 8) "\00\00\00\00\00\00\00\80") ;; -0.0 le bytes
(func (export "via_local") (result i64)
(local f64)
(local.set 0 (f64.const -0))
(i64.reinterpret_f64 (local.get 0)))
(func (export "via_block") (result i64)
(i64.reinterpret_f64 (block (result f64) (f64.const -0))))
(func (export "via_phi") (param i32) (result i64)
(local f64)
(if (local.get 0)
(then (local.set 1 (f64.const -0)))
(else (local.set 1 (f64.const 1))))
(i64.reinterpret_f64 (local.get 1)))
(func (export "via_select") (param i32) (result i64)
(i64.reinterpret_f64
(select (f64.const -0) (f64.const 2) (local.get 0))))
(func (export "via_copysign_cc") (result i64)
(i64.reinterpret_f64 (f64.copysign (f64.const 0) (f64.const -1))))
(func (export "via_copysign_cv") (result i64)
;; sign source is a runtime -0 built by neg, not a parameter
(i64.reinterpret_f64 (f64.copysign (f64.const 0) (f64.neg (f64.const 0)))))
(func (export "via_copysign_vc") (result i64)
(i64.reinterpret_f64 (f64.copysign (f64.const 0) (f64.const -1))))
(func (export "via_neg_zero") (result i64)
(i64.reinterpret_f64 (f64.neg (f64.const 0))))
(func (export "via_load") (result i64)
(i64.reinterpret_f64 (f64.load (i32.const 8))))
(func (export "via_add") (result i64)
(i64.reinterpret_f64 (f64.add (f64.const -0) (f64.const -0))))
(func (export "via_mul_neg1") (result i64)
(i64.reinterpret_f64 (f64.mul (f64.const 0) (f64.const -1))))
)