aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile')
-rw-r--r--src/cmd/compile/internal/ssa/_gen/Wasm.rules7
-rw-r--r--src/cmd/compile/internal/ssa/rewriteWasm.go60
2 files changed, 67 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/Wasm.rules b/src/cmd/compile/internal/ssa/_gen/Wasm.rules
index 3fef540658..31d37db657 100644
--- a/src/cmd/compile/internal/ssa/_gen/Wasm.rules
+++ b/src/cmd/compile/internal/ssa/_gen/Wasm.rules
@@ -412,6 +412,13 @@
(I64Extend32S (I64Extend8S x)) => (I64Extend8S x)
(I64Extend16S (I64Extend8S x)) => (I64Extend8S x)
+// Sign-extend of a value already zero-extended from fewer bits is a no-op.
+// E.g. (I64Extend32S (I64And x (I64Const [0xff]))) — top 33 bits are already
+// zero, so sign-extending from 32 is identity.
+(I64Extend32S x:(I64And _ (I64Const [c]))) && c >= 0 && int64(int32(c)) == c => x
+(I64Extend16S x:(I64And _ (I64Const [c]))) && c >= 0 && int64(int16(c)) == c => x
+(I64Extend8S x:(I64And _ (I64Const [c]))) && c >= 0 && int64(int8(c)) == c => 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]))
diff --git a/src/cmd/compile/internal/ssa/rewriteWasm.go b/src/cmd/compile/internal/ssa/rewriteWasm.go
index 80c7855a45..1c9f5073e3 100644
--- a/src/cmd/compile/internal/ssa/rewriteWasm.go
+++ b/src/cmd/compile/internal/ssa/rewriteWasm.go
@@ -4135,6 +4135,26 @@ func rewriteValueWasm_OpWasmI64Extend16S(v *Value) bool {
v.AddArg(x)
return true
}
+ // match: (I64Extend16S x:(I64And _ (I64Const [c])))
+ // cond: c >= 0 && int64(int16(c)) == c
+ // result: x
+ for {
+ x := v_0
+ if x.Op != OpWasmI64And {
+ break
+ }
+ _ = x.Args[1]
+ x_1 := x.Args[1]
+ if x_1.Op != OpWasmI64Const {
+ break
+ }
+ c := auxIntToInt64(x_1.AuxInt)
+ if !(c >= 0 && int64(int16(c)) == c) {
+ break
+ }
+ v.copyOf(x)
+ return true
+ }
return false
}
func rewriteValueWasm_OpWasmI64Extend32S(v *Value) bool {
@@ -4172,6 +4192,26 @@ func rewriteValueWasm_OpWasmI64Extend32S(v *Value) bool {
v.AddArg(x)
return true
}
+ // match: (I64Extend32S x:(I64And _ (I64Const [c])))
+ // cond: c >= 0 && int64(int32(c)) == c
+ // result: x
+ for {
+ x := v_0
+ if x.Op != OpWasmI64And {
+ break
+ }
+ _ = x.Args[1]
+ x_1 := x.Args[1]
+ if x_1.Op != OpWasmI64Const {
+ break
+ }
+ c := auxIntToInt64(x_1.AuxInt)
+ if !(c >= 0 && int64(int32(c)) == c) {
+ break
+ }
+ v.copyOf(x)
+ return true
+ }
return false
}
func rewriteValueWasm_OpWasmI64Extend8S(v *Value) bool {
@@ -4187,6 +4227,26 @@ func rewriteValueWasm_OpWasmI64Extend8S(v *Value) bool {
v.AddArg(x)
return true
}
+ // match: (I64Extend8S x:(I64And _ (I64Const [c])))
+ // cond: c >= 0 && int64(int8(c)) == c
+ // result: x
+ for {
+ x := v_0
+ if x.Op != OpWasmI64And {
+ break
+ }
+ _ = x.Args[1]
+ x_1 := x.Args[1]
+ if x_1.Op != OpWasmI64Const {
+ break
+ }
+ c := auxIntToInt64(x_1.AuxInt)
+ if !(c >= 0 && int64(int8(c)) == c) {
+ break
+ }
+ v.copyOf(x)
+ return true
+ }
return false
}
func rewriteValueWasm_OpWasmI64LeU(v *Value) bool {