mirror of
https://github.com/golang/go.git
synced 2026-04-02 09:20:29 +09:00
cmd/compile: eliminate redundant sign-extensions for wasm
Add rules to eliminate redundant I64Extend sign-extension operations in the wasm backend: Idempotent (applying the same extend twice is redundant): (I64Extend32S (I64Extend32S x)) => (I64Extend32S x) (I64Extend16S (I64Extend16S x)) => (I64Extend16S x) (I64Extend8S (I64Extend8S x)) => (I64Extend8S x) Narrower-subsumes-wider (a narrower sign-extend already determines all the bits that a wider one would set): (I64Extend32S (I64Extend16S x)) => (I64Extend16S x) (I64Extend32S (I64Extend8S x)) => (I64Extend8S x) (I64Extend16S (I64Extend8S x)) => (I64Extend8S x) These patterns arise from nested sub-word type conversions. For example, converting int8 -> int16 -> int32 -> int64 lowers to I64Extend8S -> I64Extend16S -> I64Extend32S, but the I64Extend8S alone is sufficient since it already sign-extends from 8 to 64 bits. Cq-Include-Trybots: luci.golang.try:gotip-wasip1-wasm_wasmtime,gotip-wasip1-wasm_wazero Change-Id: I1637687df31893b1ffa36915a3bd2e10d455f4ef Reviewed-on: https://go-review.googlesource.com/c/go/+/754040 Reviewed-by: Carlos Amedee <carlos@golang.org> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
committed by
Gopher Robot
parent
75fdbda517
commit
65f76a20a3
@@ -404,6 +404,14 @@
|
||||
// (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]))
|
||||
|
||||
// Redundant sign-extensions: idempotent and narrower-subsumes-wider.
|
||||
(I64Extend32S (I64Extend32S x)) => (I64Extend32S x)
|
||||
(I64Extend16S (I64Extend16S x)) => (I64Extend16S x)
|
||||
(I64Extend8S (I64Extend8S x)) => (I64Extend8S x)
|
||||
(I64Extend32S (I64Extend16S x)) => (I64Extend16S x)
|
||||
(I64Extend32S (I64Extend8S x)) => (I64Extend8S x)
|
||||
(I64Extend16S (I64Extend8S x)) => (I64Extend8S x)
|
||||
|
||||
// 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]))
|
||||
|
||||
@@ -618,6 +618,12 @@ func rewriteValueWasm(v *Value) bool {
|
||||
return rewriteValueWasm_OpWasmI64Eq(v)
|
||||
case OpWasmI64Eqz:
|
||||
return rewriteValueWasm_OpWasmI64Eqz(v)
|
||||
case OpWasmI64Extend16S:
|
||||
return rewriteValueWasm_OpWasmI64Extend16S(v)
|
||||
case OpWasmI64Extend32S:
|
||||
return rewriteValueWasm_OpWasmI64Extend32S(v)
|
||||
case OpWasmI64Extend8S:
|
||||
return rewriteValueWasm_OpWasmI64Extend8S(v)
|
||||
case OpWasmI64LeU:
|
||||
return rewriteValueWasm_OpWasmI64LeU(v)
|
||||
case OpWasmI64Load:
|
||||
@@ -4105,6 +4111,84 @@ func rewriteValueWasm_OpWasmI64Eqz(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueWasm_OpWasmI64Extend16S(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (I64Extend16S (I64Extend16S x))
|
||||
// result: (I64Extend16S x)
|
||||
for {
|
||||
if v_0.Op != OpWasmI64Extend16S {
|
||||
break
|
||||
}
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpWasmI64Extend16S)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (I64Extend16S (I64Extend8S x))
|
||||
// result: (I64Extend8S x)
|
||||
for {
|
||||
if v_0.Op != OpWasmI64Extend8S {
|
||||
break
|
||||
}
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpWasmI64Extend8S)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueWasm_OpWasmI64Extend32S(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (I64Extend32S (I64Extend32S x))
|
||||
// result: (I64Extend32S x)
|
||||
for {
|
||||
if v_0.Op != OpWasmI64Extend32S {
|
||||
break
|
||||
}
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpWasmI64Extend32S)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (I64Extend32S (I64Extend16S x))
|
||||
// result: (I64Extend16S x)
|
||||
for {
|
||||
if v_0.Op != OpWasmI64Extend16S {
|
||||
break
|
||||
}
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpWasmI64Extend16S)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (I64Extend32S (I64Extend8S x))
|
||||
// result: (I64Extend8S x)
|
||||
for {
|
||||
if v_0.Op != OpWasmI64Extend8S {
|
||||
break
|
||||
}
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpWasmI64Extend8S)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueWasm_OpWasmI64Extend8S(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (I64Extend8S (I64Extend8S x))
|
||||
// result: (I64Extend8S x)
|
||||
for {
|
||||
if v_0.Op != OpWasmI64Extend8S {
|
||||
break
|
||||
}
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpWasmI64Extend8S)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueWasm_OpWasmI64LeU(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
|
||||
Reference in New Issue
Block a user