aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorGeorge Adams <georgeadams1995@gmail.com>2026-03-10 12:36:29 +0000
committerGopher Robot <gobot@golang.org>2026-03-10 20:07:23 -0700
commitbd5dc3a2fbde68835326d3b1d9fc480bcf6da086 (patch)
tree15a668002ca196d031bdf912cf317634b129468e /src/cmd
parent935ba2e486d035c60104217eec8f2a223cdb3bef (diff)
downloadgo-bd5dc3a2fbde68835326d3b1d9fc480bcf6da086.tar.xz
cmd/compile: add double-mask elimination rule for wasm
Add a rule to collapse cascaded I64And operations with constant masks into a single mask: (I64And (I64And x (I64Const [c1])) (I64Const [c2])) => (I64And x (I64Const [c1 & c2])) This pattern arises from sub-word comparisons. For example, (Eq32 x y) lowers to (I64Eq (ZeroExt32to64 x) (ZeroExt32to64 y)), which becomes (I64Eq (I64And x 0xffffffff) (I64And y 0xffffffff)). If x or y is the result of another sub-word operation that already inserted a mask, the masks cascade and this rule collapses them. Cq-Include-Trybots: luci.golang.try:gotip-wasip1-wasm_wasmtime,gotip-wasip1-wasm_wazero Change-Id: Id7856b391be3ac20f1bc9eee40995b52c0754aed Reviewed-on: https://go-review.googlesource.com/c/go/+/753620 Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Mark Freeman <markfreeman@google.com> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/compile/internal/ssa/_gen/Wasm.rules4
-rw-r--r--src/cmd/compile/internal/ssa/rewriteWasm.go23
2 files changed, 27 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/Wasm.rules b/src/cmd/compile/internal/ssa/_gen/Wasm.rules
index 9b582c8c00..5e0c9304b5 100644
--- a/src/cmd/compile/internal/ssa/_gen/Wasm.rules
+++ b/src/cmd/compile/internal/ssa/_gen/Wasm.rules
@@ -400,6 +400,10 @@
(I64Mul x (I64Const [0])) => (I64Const [0])
(I64Mul x (I64Const [1])) => x
+// Double-mask elimination: cascaded zero-extensions produce
+// (I64And (I64And x C1) C2) which can be collapsed to a single mask.
+(I64And (I64And x (I64Const [c1])) (I64Const [c2])) => (I64And x (I64Const [c1 & c2]))
+
// TODO: declare these operations as commutative and get rid of these rules?
(I64Add (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Add y (I64Const [x]))
(I64Mul (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Mul y (I64Const [x]))
diff --git a/src/cmd/compile/internal/ssa/rewriteWasm.go b/src/cmd/compile/internal/ssa/rewriteWasm.go
index c0ccd9611d..80c783e568 100644
--- a/src/cmd/compile/internal/ssa/rewriteWasm.go
+++ b/src/cmd/compile/internal/ssa/rewriteWasm.go
@@ -3969,6 +3969,29 @@ func rewriteValueWasm_OpWasmI64And(v *Value) bool {
v.AuxInt = int64ToAuxInt(0)
return true
}
+ // match: (I64And (I64And x (I64Const [c1])) (I64Const [c2]))
+ // result: (I64And x (I64Const [c1 & c2]))
+ for {
+ if v_0.Op != OpWasmI64And {
+ break
+ }
+ _ = v_0.Args[1]
+ x := v_0.Args[0]
+ v_0_1 := v_0.Args[1]
+ if v_0_1.Op != OpWasmI64Const {
+ break
+ }
+ c1 := auxIntToInt64(v_0_1.AuxInt)
+ if v_1.Op != OpWasmI64Const {
+ break
+ }
+ c2 := auxIntToInt64(v_1.AuxInt)
+ v.reset(OpWasmI64And)
+ v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
+ v0.AuxInt = int64ToAuxInt(c1 & c2)
+ v.AddArg2(x, v0)
+ return true
+ }
// match: (I64And (I64Const [x]) y)
// cond: y.Op != OpWasmI64Const
// result: (I64And y (I64Const [x]))