]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile, runtime: always enable Wasm signext and satconv features
authorCherry Mui <cherryyz@google.com>
Mon, 29 Sep 2025 20:14:24 +0000 (16:14 -0400)
committerDavid Chase <drchase@google.com>
Tue, 30 Sep 2025 13:37:45 +0000 (06:37 -0700)
These features have been standardized since at least Wasm 2.0.
Always enable them.

The corresponding GOWASM settings are now no-op.

Change-Id: I0e59f21696a69a4e289127988aad629a720b002b
Reviewed-on: https://go-review.googlesource.com/c/go/+/707855
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/_gen/Wasm.rules
src/cmd/compile/internal/ssa/rewriteWasm.go
src/cmd/compile/internal/wasm/ssa.go
src/internal/buildcfg/cfg.go
src/runtime/conv_wasm_test.go
src/runtime/sys_wasm.s

index f3bd8d8b4f18f1c812ee00b8606beacffe7e5fba..f632a01109f764c8dace73cf2c01ad75ca26d5f3 100644 (file)
 (ZeroExt32to64        x:(I64Load32U _ _)) => x
 (ZeroExt16to(64|32)   x:(I64Load16U _ _)) => x
 (ZeroExt8to(64|32|16) x:(I64Load8U  _ _)) => x
-(SignExt32to64        x) && buildcfg.GOWASM.SignExt => (I64Extend32S x)
-(SignExt8to(64|32|16) x) && buildcfg.GOWASM.SignExt => (I64Extend8S x)
-(SignExt16to(64|32)   x) && buildcfg.GOWASM.SignExt => (I64Extend16S x)
-(SignExt32to64        x) => (I64ShrS (I64Shl x (I64Const [32])) (I64Const [32]))
-(SignExt16to(64|32)   x) => (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
-(SignExt8to(64|32|16) x) => (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
+(SignExt32to64        x) => (I64Extend32S x)
+(SignExt8to(64|32|16) x) => (I64Extend8S x)
+(SignExt16to(64|32)   x) => (I64Extend16S x)
 (ZeroExt32to64        x) => (I64And x (I64Const [0xffffffff]))
 (ZeroExt16to(64|32)   x) => (I64And x (I64Const [0xffff]))
 (ZeroExt8to(64|32|16) x) => (I64And x (I64Const [0xff]))
index c3c5528aaa6ab4690f3351e8331056d124a2e876..a164a6eee555b945c471799b9d7a2b544f6fc070 100644 (file)
@@ -2,7 +2,6 @@
 
 package ssa
 
-import "internal/buildcfg"
 import "math"
 import "cmd/compile/internal/types"
 
@@ -3202,8 +3201,6 @@ func rewriteValueWasm_OpRsh8x8(v *Value) bool {
 }
 func rewriteValueWasm_OpSignExt16to32(v *Value) bool {
        v_0 := v.Args[0]
-       b := v.Block
-       typ := &b.Func.Config.Types
        // match: (SignExt16to32 x:(I64Load16S _ _))
        // result: x
        for {
@@ -3215,34 +3212,16 @@ func rewriteValueWasm_OpSignExt16to32(v *Value) bool {
                return true
        }
        // match: (SignExt16to32 x)
-       // cond: buildcfg.GOWASM.SignExt
        // result: (I64Extend16S x)
        for {
                x := v_0
-               if !(buildcfg.GOWASM.SignExt) {
-                       break
-               }
                v.reset(OpWasmI64Extend16S)
                v.AddArg(x)
                return true
        }
-       // match: (SignExt16to32 x)
-       // result: (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
-       for {
-               x := v_0
-               v.reset(OpWasmI64ShrS)
-               v0 := b.NewValue0(v.Pos, OpWasmI64Shl, typ.Int64)
-               v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
-               v1.AuxInt = int64ToAuxInt(48)
-               v0.AddArg2(x, v1)
-               v.AddArg2(v0, v1)
-               return true
-       }
 }
 func rewriteValueWasm_OpSignExt16to64(v *Value) bool {
        v_0 := v.Args[0]
-       b := v.Block
-       typ := &b.Func.Config.Types
        // match: (SignExt16to64 x:(I64Load16S _ _))
        // result: x
        for {
@@ -3254,34 +3233,16 @@ func rewriteValueWasm_OpSignExt16to64(v *Value) bool {
                return true
        }
        // match: (SignExt16to64 x)
-       // cond: buildcfg.GOWASM.SignExt
        // result: (I64Extend16S x)
        for {
                x := v_0
-               if !(buildcfg.GOWASM.SignExt) {
-                       break
-               }
                v.reset(OpWasmI64Extend16S)
                v.AddArg(x)
                return true
        }
-       // match: (SignExt16to64 x)
-       // result: (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
-       for {
-               x := v_0
-               v.reset(OpWasmI64ShrS)
-               v0 := b.NewValue0(v.Pos, OpWasmI64Shl, typ.Int64)
-               v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
-               v1.AuxInt = int64ToAuxInt(48)
-               v0.AddArg2(x, v1)
-               v.AddArg2(v0, v1)
-               return true
-       }
 }
 func rewriteValueWasm_OpSignExt32to64(v *Value) bool {
        v_0 := v.Args[0]
-       b := v.Block
-       typ := &b.Func.Config.Types
        // match: (SignExt32to64 x:(I64Load32S _ _))
        // result: x
        for {
@@ -3293,34 +3254,16 @@ func rewriteValueWasm_OpSignExt32to64(v *Value) bool {
                return true
        }
        // match: (SignExt32to64 x)
-       // cond: buildcfg.GOWASM.SignExt
        // result: (I64Extend32S x)
        for {
                x := v_0
-               if !(buildcfg.GOWASM.SignExt) {
-                       break
-               }
                v.reset(OpWasmI64Extend32S)
                v.AddArg(x)
                return true
        }
-       // match: (SignExt32to64 x)
-       // result: (I64ShrS (I64Shl x (I64Const [32])) (I64Const [32]))
-       for {
-               x := v_0
-               v.reset(OpWasmI64ShrS)
-               v0 := b.NewValue0(v.Pos, OpWasmI64Shl, typ.Int64)
-               v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
-               v1.AuxInt = int64ToAuxInt(32)
-               v0.AddArg2(x, v1)
-               v.AddArg2(v0, v1)
-               return true
-       }
 }
 func rewriteValueWasm_OpSignExt8to16(v *Value) bool {
        v_0 := v.Args[0]
-       b := v.Block
-       typ := &b.Func.Config.Types
        // match: (SignExt8to16 x:(I64Load8S _ _))
        // result: x
        for {
@@ -3332,34 +3275,16 @@ func rewriteValueWasm_OpSignExt8to16(v *Value) bool {
                return true
        }
        // match: (SignExt8to16 x)
-       // cond: buildcfg.GOWASM.SignExt
        // result: (I64Extend8S x)
        for {
                x := v_0
-               if !(buildcfg.GOWASM.SignExt) {
-                       break
-               }
                v.reset(OpWasmI64Extend8S)
                v.AddArg(x)
                return true
        }
-       // match: (SignExt8to16 x)
-       // result: (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
-       for {
-               x := v_0
-               v.reset(OpWasmI64ShrS)
-               v0 := b.NewValue0(v.Pos, OpWasmI64Shl, typ.Int64)
-               v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
-               v1.AuxInt = int64ToAuxInt(56)
-               v0.AddArg2(x, v1)
-               v.AddArg2(v0, v1)
-               return true
-       }
 }
 func rewriteValueWasm_OpSignExt8to32(v *Value) bool {
        v_0 := v.Args[0]
-       b := v.Block
-       typ := &b.Func.Config.Types
        // match: (SignExt8to32 x:(I64Load8S _ _))
        // result: x
        for {
@@ -3371,34 +3296,16 @@ func rewriteValueWasm_OpSignExt8to32(v *Value) bool {
                return true
        }
        // match: (SignExt8to32 x)
-       // cond: buildcfg.GOWASM.SignExt
        // result: (I64Extend8S x)
        for {
                x := v_0
-               if !(buildcfg.GOWASM.SignExt) {
-                       break
-               }
                v.reset(OpWasmI64Extend8S)
                v.AddArg(x)
                return true
        }
-       // match: (SignExt8to32 x)
-       // result: (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
-       for {
-               x := v_0
-               v.reset(OpWasmI64ShrS)
-               v0 := b.NewValue0(v.Pos, OpWasmI64Shl, typ.Int64)
-               v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
-               v1.AuxInt = int64ToAuxInt(56)
-               v0.AddArg2(x, v1)
-               v.AddArg2(v0, v1)
-               return true
-       }
 }
 func rewriteValueWasm_OpSignExt8to64(v *Value) bool {
        v_0 := v.Args[0]
-       b := v.Block
-       typ := &b.Func.Config.Types
        // match: (SignExt8to64 x:(I64Load8S _ _))
        // result: x
        for {
@@ -3410,29 +3317,13 @@ func rewriteValueWasm_OpSignExt8to64(v *Value) bool {
                return true
        }
        // match: (SignExt8to64 x)
-       // cond: buildcfg.GOWASM.SignExt
        // result: (I64Extend8S x)
        for {
                x := v_0
-               if !(buildcfg.GOWASM.SignExt) {
-                       break
-               }
                v.reset(OpWasmI64Extend8S)
                v.AddArg(x)
                return true
        }
-       // match: (SignExt8to64 x)
-       // result: (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
-       for {
-               x := v_0
-               v.reset(OpWasmI64ShrS)
-               v0 := b.NewValue0(v.Pos, OpWasmI64Shl, typ.Int64)
-               v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
-               v1.AuxInt = int64ToAuxInt(56)
-               v0.AddArg2(x, v1)
-               v.AddArg2(v0, v1)
-               return true
-       }
 }
 func rewriteValueWasm_OpSlicemask(v *Value) bool {
        v_0 := v.Args[0]
index daee82f1fd73664ad0e213ebab4e38ad84ae793c..1e3b318e8c9fe0980770453795c14017d745a3df 100644 (file)
@@ -14,7 +14,6 @@ import (
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/obj/wasm"
-       "internal/buildcfg"
 )
 
 /*
@@ -425,27 +424,11 @@ func ssaGenValueOnStack(s *ssagen.State, v *ssa.Value, extend bool) {
 
        case ssa.OpWasmI64TruncSatF32S, ssa.OpWasmI64TruncSatF64S:
                getValue64(s, v.Args[0])
-               if buildcfg.GOWASM.SatConv {
-                       s.Prog(v.Op.Asm())
-               } else {
-                       if v.Op == ssa.OpWasmI64TruncSatF32S {
-                               s.Prog(wasm.AF64PromoteF32)
-                       }
-                       p := s.Prog(wasm.ACall)
-                       p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: ir.Syms.WasmTruncS}
-               }
+               s.Prog(v.Op.Asm())
 
        case ssa.OpWasmI64TruncSatF32U, ssa.OpWasmI64TruncSatF64U:
                getValue64(s, v.Args[0])
-               if buildcfg.GOWASM.SatConv {
-                       s.Prog(v.Op.Asm())
-               } else {
-                       if v.Op == ssa.OpWasmI64TruncSatF32U {
-                               s.Prog(wasm.AF64PromoteF32)
-                       }
-                       p := s.Prog(wasm.ACall)
-                       p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: ir.Syms.WasmTruncU}
-               }
+               s.Prog(v.Op.Asm())
 
        case ssa.OpWasmF32DemoteF64:
                getValue64(s, v.Args[0])
index 9ab29568d22704148bc0b8a660c91ac47f8a12c8..a75960b8e6c0345c0224cbba8ac5f2e3995940a0 100644 (file)
@@ -321,18 +321,13 @@ func goriscv64() int {
 }
 
 type gowasmFeatures struct {
-       SatConv bool
-       SignExt bool
+       // Legacy features, now always enabled
+       //SatConv bool
+       //SignExt bool
 }
 
 func (f gowasmFeatures) String() string {
        var flags []string
-       if f.SatConv {
-               flags = append(flags, "satconv")
-       }
-       if f.SignExt {
-               flags = append(flags, "signext")
-       }
        return strings.Join(flags, ",")
 }
 
@@ -340,9 +335,9 @@ func gowasm() (f gowasmFeatures) {
        for opt := range strings.SplitSeq(envOr("GOWASM", ""), ",") {
                switch opt {
                case "satconv":
-                       f.SatConv = true
+                       // ignore, always enabled
                case "signext":
-                       f.SignExt = true
+                       // ignore, always enabled
                case "":
                        // ignore
                default:
@@ -452,12 +447,10 @@ func gogoarchTags() []string {
                return list
        case "wasm":
                var list []string
-               if GOWASM.SatConv {
-                       list = append(list, GOARCH+".satconv")
-               }
-               if GOWASM.SignExt {
-                       list = append(list, GOARCH+".signext")
-               }
+               // SatConv is always enabled
+               list = append(list, GOARCH+".satconv")
+               // SignExt is always enabled
+               list = append(list, GOARCH+".signext")
                return list
        }
        return nil
index 5054fca04dc40a8b65c30e9451112d907c166ed1..3979a7b618028b75055e59a142737bd766b33d34 100644 (file)
@@ -11,6 +11,8 @@ import (
 var res int64
 var ures uint64
 
+// TODO: This test probably should be in a different place.
+
 func TestFloatTruncation(t *testing.T) {
        testdata := []struct {
                input      float64
@@ -21,36 +23,37 @@ func TestFloatTruncation(t *testing.T) {
                // max +- 1
                {
                        input:      0x7fffffffffffffff,
-                       convInt64:  -0x8000000000000000,
+                       convInt64:  0x7fffffffffffffff,
                        convUInt64: 0x8000000000000000,
                },
                // For out-of-bounds conversion, the result is implementation-dependent.
-               // This test verifies the implementation of wasm architecture.
+               // This test verifies the implementation of wasm architecture, which is,
+               // saturating to the min/max value.
                {
                        input:      0x8000000000000000,
-                       convInt64:  -0x8000000000000000,
+                       convInt64:  0x7fffffffffffffff,
                        convUInt64: 0x8000000000000000,
                },
                {
                        input:      0x7ffffffffffffffe,
-                       convInt64:  -0x8000000000000000,
+                       convInt64:  0x7fffffffffffffff,
                        convUInt64: 0x8000000000000000,
                },
                // neg max +- 1
                {
                        input:      -0x8000000000000000,
                        convInt64:  -0x8000000000000000,
-                       convUInt64: 0x8000000000000000,
+                       convUInt64: 0,
                },
                {
                        input:      -0x8000000000000001,
                        convInt64:  -0x8000000000000000,
-                       convUInt64: 0x8000000000000000,
+                       convUInt64: 0,
                },
                {
                        input:      -0x7fffffffffffffff,
                        convInt64:  -0x8000000000000000,
-                       convUInt64: 0x8000000000000000,
+                       convUInt64: 0,
                },
                // trunc point +- 1
                {
@@ -60,7 +63,7 @@ func TestFloatTruncation(t *testing.T) {
                },
                {
                        input:      0x7ffffffffffffe00,
-                       convInt64:  -0x8000000000000000,
+                       convInt64:  0x7fffffffffffffff,
                        convUInt64: 0x8000000000000000,
                },
                {
@@ -72,48 +75,48 @@ func TestFloatTruncation(t *testing.T) {
                {
                        input:      -0x7ffffffffffffdff,
                        convInt64:  -0x7ffffffffffffc00,
-                       convUInt64: 0x8000000000000000,
+                       convUInt64: 0,
                },
                {
                        input:      -0x7ffffffffffffe00,
                        convInt64:  -0x8000000000000000,
-                       convUInt64: 0x8000000000000000,
+                       convUInt64: 0,
                },
                {
                        input:      -0x7ffffffffffffdfe,
                        convInt64:  -0x7ffffffffffffc00,
-                       convUInt64: 0x8000000000000000,
+                       convUInt64: 0,
                },
                // umax +- 1
                {
                        input:      0xffffffffffffffff,
-                       convInt64:  -0x8000000000000000,
-                       convUInt64: 0x8000000000000000,
+                       convInt64:  0x7fffffffffffffff,
+                       convUInt64: 0xffffffffffffffff,
                },
                {
                        input:      0x10000000000000000,
-                       convInt64:  -0x8000000000000000,
-                       convUInt64: 0x8000000000000000,
+                       convInt64:  0x7fffffffffffffff,
+                       convUInt64: 0xffffffffffffffff,
                },
                {
                        input:      0xfffffffffffffffe,
-                       convInt64:  -0x8000000000000000,
-                       convUInt64: 0x8000000000000000,
+                       convInt64:  0x7fffffffffffffff,
+                       convUInt64: 0xffffffffffffffff,
                },
                // umax trunc +- 1
                {
                        input:      0xfffffffffffffbff,
-                       convInt64:  -0x8000000000000000,
+                       convInt64:  0x7fffffffffffffff,
                        convUInt64: 0xfffffffffffff800,
                },
                {
                        input:      0xfffffffffffffc00,
-                       convInt64:  -0x8000000000000000,
-                       convUInt64: 0x8000000000000000,
+                       convInt64:  0x7fffffffffffffff,
+                       convUInt64: 0xffffffffffffffff,
                },
                {
                        input:      0xfffffffffffffbfe,
-                       convInt64:  -0x8000000000000000,
+                       convInt64:  0x7fffffffffffffff,
                        convUInt64: 0xfffffffffffff800,
                },
        }
index b7965ec3fa4138454e6a2fd843e80abec19c065f..95c162eb857ac4b489cb6d2430183cc2f1169cf3 100644 (file)
@@ -22,64 +22,6 @@ TEXT runtime·wasmDiv(SB), NOSPLIT, $0-0
        I64DivS
        Return
 
-TEXT runtime·wasmTruncS(SB), NOSPLIT, $0-0
-       Get R0
-       Get R0
-       F64Ne // NaN
-       If
-               I64Const $0x8000000000000000
-               Return
-       End
-
-       Get R0
-       F64Const $0x7ffffffffffffc00p0 // Maximum truncated representation of 0x7fffffffffffffff
-       F64Gt
-       If
-               I64Const $0x8000000000000000
-               Return
-       End
-
-       Get R0
-       F64Const $-0x7ffffffffffffc00p0 // Minimum truncated representation of -0x8000000000000000
-       F64Lt
-       If
-               I64Const $0x8000000000000000
-               Return
-       End
-
-       Get R0
-       I64TruncF64S
-       Return
-
-TEXT runtime·wasmTruncU(SB), NOSPLIT, $0-0
-       Get R0
-       Get R0
-       F64Ne // NaN
-       If
-               I64Const $0x8000000000000000
-               Return
-       End
-
-       Get R0
-       F64Const $0xfffffffffffff800p0 // Maximum truncated representation of 0xffffffffffffffff
-       F64Gt
-       If
-               I64Const $0x8000000000000000
-               Return
-       End
-
-       Get R0
-       F64Const $0.
-       F64Lt
-       If
-               I64Const $0x8000000000000000
-               Return
-       End
-
-       Get R0
-       I64TruncF64U
-       Return
-
 TEXT runtime·exitThread(SB), NOSPLIT, $0-0
        UNDEF