From b764d47e4dbc4d38689728b712b60bfc47d77128 Mon Sep 17 00:00:00 2001 From: George Adams Date: Wed, 4 Mar 2026 13:45:31 +0000 Subject: [PATCH] cmd/compile: add I64Sub constant folding rule for wasm Add the missing I64Sub constant folding rule to the wasm backend. Every other wasm arithmetic operation (I64Add, I64Mul, I64And, I64Or, I64Xor, I64Shl, I64ShrU, I64ShrS) already had a post-lowering constant folding rule, but I64Sub was missing. While the generic SSA pass folds Sub64(Const64, Const64) before lowering, this rule ensures consistency and handles any edge cases where later wasm-specific passes produce I64Sub with two constant operands. Cq-Include-Trybots: luci.golang.try:gotip-wasip1-wasm_wasmtime,gotip-wasip1-wasm_wazero Change-Id: Ie8bc044dd300dcc6d077feec34f9a65f4a310b13 Reviewed-on: https://go-review.googlesource.com/c/go/+/751441 Reviewed-by: Keith Randall Auto-Submit: Keith Randall Reviewed-by: Keith Randall Reviewed-by: David Chase Commit-Queue: Keith Randall LUCI-TryBot-Result: Go LUCI --- src/cmd/compile/internal/ssa/_gen/Wasm.rules | 1 + src/cmd/compile/internal/ssa/rewriteWasm.go | 22 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/cmd/compile/internal/ssa/_gen/Wasm.rules b/src/cmd/compile/internal/ssa/_gen/Wasm.rules index bf48ed4348..8490fb39b8 100644 --- a/src/cmd/compile/internal/ssa/_gen/Wasm.rules +++ b/src/cmd/compile/internal/ssa/_gen/Wasm.rules @@ -374,6 +374,7 @@ // --- Optimizations --- (I64Add (I64Const [x]) (I64Const [y])) => (I64Const [x + y]) +(I64Sub (I64Const [x]) (I64Const [y])) => (I64Const [x - y]) (I64Mul (I64Const [x]) (I64Const [y])) => (I64Const [x * y]) (I64And (I64Const [x]) (I64Const [y])) => (I64Const [x & y]) (I64Or (I64Const [x]) (I64Const [y])) => (I64Const [x | y]) diff --git a/src/cmd/compile/internal/ssa/rewriteWasm.go b/src/cmd/compile/internal/ssa/rewriteWasm.go index 94535bfbc7..68a40f0c7f 100644 --- a/src/cmd/compile/internal/ssa/rewriteWasm.go +++ b/src/cmd/compile/internal/ssa/rewriteWasm.go @@ -656,6 +656,8 @@ func rewriteValueWasm(v *Value) bool { return rewriteValueWasm_OpWasmI64Store32(v) case OpWasmI64Store8: return rewriteValueWasm_OpWasmI64Store8(v) + case OpWasmI64Sub: + return rewriteValueWasm_OpWasmI64Sub(v) case OpWasmI64Xor: return rewriteValueWasm_OpWasmI64Xor(v) case OpXor16: @@ -4746,6 +4748,26 @@ func rewriteValueWasm_OpWasmI64Store8(v *Value) bool { } return false } +func rewriteValueWasm_OpWasmI64Sub(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (I64Sub (I64Const [x]) (I64Const [y])) + // result: (I64Const [x - y]) + for { + if v_0.Op != OpWasmI64Const { + break + } + x := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpWasmI64Const { + break + } + y := auxIntToInt64(v_1.AuxInt) + v.reset(OpWasmI64Const) + v.AuxInt = int64ToAuxInt(x - y) + return true + } + return false +} func rewriteValueWasm_OpWasmI64Xor(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0]