cmd/compile, simd/archsimd: make Wasm Get/SetElem work for out-of-bound constants Currently, an out-of-bound constant index of GetElem or SetElem can generate code that is failed to verify with the Wasm engine. Fix it by handling out-of-bound constant the same way as dynamic values. Make GetElem/SetElem tests portable. Change-Id: I0e36b48c2b020a24286c257ee2c778b0041993e3 Reviewed-on: https://go-review.googlesource.com/c/go/+/794122 Reviewed-by: David Chase <drchase@google.com> TryBot-Bypass: Cherry Mui <cherryyz@google.com>
diff --git a/src/cmd/compile/internal/ssagen/simdWasmintrinsics.go b/src/cmd/compile/internal/ssagen/simdWasmintrinsics.go index f50d947..9a92cf8 100644 --- a/src/cmd/compile/internal/ssagen/simdWasmintrinsics.go +++ b/src/cmd/compile/internal/ssagen/simdWasmintrinsics.go
@@ -43,7 +43,7 @@ makeSimdOp1Imm8 := func(op ssa.Op, immLimit uint64) func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { t := n.Type() - if args[1].Op == ssa.OpConst8 { + if args[1].Op == ssa.OpConst8 && uint64(args[1].AuxInt) < immLimit { return s.newValue1I(op, t, args[1].AuxInt, args[0]) } return immJumpTableN(s, args[1], n, immLimit, func(sNew *state, idx int) { @@ -56,7 +56,7 @@ makeSimdOp2Imm8 := func(op ssa.Op, immLimit uint64) func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { t := types.TypeVec128 - if args[1].Op == ssa.OpConst8 { + if args[1].Op == ssa.OpConst8 && uint64(args[1].AuxInt) < immLimit { return s.newValue2I(op, t, args[1].AuxInt, args[0], args[2]) } return immJumpTableN(s, args[1], n, immLimit, func(sNew *state, idx int) {
diff --git a/src/simd/archsimd/_gen/wasmgen/main.go b/src/simd/archsimd/_gen/wasmgen/main.go index 90c783c..b73cff8 100644 --- a/src/simd/archsimd/_gen/wasmgen/main.go +++ b/src/simd/archsimd/_gen/wasmgen/main.go
@@ -1947,7 +1947,7 @@ makeSimdOp1Imm8 := func(op ssa.Op, immLimit uint64) func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { t := n.Type() - if args[1].Op == ssa.OpConst8 { + if args[1].Op == ssa.OpConst8 && uint64(args[1].AuxInt) < immLimit { return s.newValue1I(op, t, args[1].AuxInt, args[0]) } return immJumpTableN(s, args[1], n, immLimit, func(sNew *state, idx int) { @@ -1960,7 +1960,7 @@ makeSimdOp2Imm8 := func(op ssa.Op, immLimit uint64) func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { t := types.TypeVec128 - if args[1].Op == ssa.OpConst8 { + if args[1].Op == ssa.OpConst8 && uint64(args[1].AuxInt) < immLimit { return s.newValue2I(op, t, args[1].AuxInt, args[0], args[2]) } return immJumpTableN(s, args[1], n, immLimit, func(sNew *state, idx int) {
diff --git a/src/simd/archsimd/internal/simd_test/simd_amd64_test.go b/src/simd/archsimd/internal/simd_test/simd_amd64_test.go index 3c2f04c..2a69b2a 100644 --- a/src/simd/archsimd/internal/simd_test/simd_amd64_test.go +++ b/src/simd/archsimd/internal/simd_test/simd_amd64_test.go
@@ -102,106 +102,6 @@ checkSlices(t, a, b) } -func TestSlicesInt8SetElem(t *testing.T) { - a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32} - v := archsimd.LoadInt8x16(a) - - v = v.SetElem(3, 13) - a[3] = 13 - - b := make([]int8, 16, 16) - v.Store(b) - checkSlices(t, a, b) -} - -func TestSlicesInt8GetElem(t *testing.T) { - a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32} - v := archsimd.LoadInt8x16(a) - e := v.GetElem(2) - if e != a[2] { - t.Errorf("GetElem(2) = %d != a[2] = %d", e, a[2]) - } - -} - -var seventeen = uint8(17) - -func TestSlicesInt8GetElem16(t *testing.T) { - defer func() { - if r := recover(); r != nil { - t.Logf("Saw EXPECTED panic %v", r) - } else { - t.Errorf("Did not see expected panic") - } - }() - a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} - v := archsimd.LoadInt8x16(a) - e := v.GetElem(seventeen - 1) - t.Errorf("Should have panicked, e=%v", e) -} - -func TestSlicesInt8GetElem16const(t *testing.T) { - defer func() { - if r := recover(); r != nil { - t.Logf("Saw EXPECTED panic %v", r) - } else { - t.Errorf("Did not see expected panic") - } - }() - a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} - v := archsimd.LoadInt8x16(a) - e := v.GetElem(16) - t.Errorf("Should have panicked, e=%v", e) -} - -func TestSlicesInt8GetElem15(t *testing.T) { - a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} - v := archsimd.LoadInt8x16(a) - e := v.GetElem(seventeen - 2) - if e != a[15] { - t.Errorf("GetElem(15) = %d != a[15] = %d", e, a[15]) - } -} - -func TestSlicesInt8GetElem15const(t *testing.T) { - a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} - v := archsimd.LoadInt8x16(a) - e := v.GetElem(15) - if e != a[15] { - t.Errorf("GetElem(15) = %d != a[15] = %d", e, a[15]) - } -} - -func TestSlicesInt8SetElem17(t *testing.T) { - defer func() { - if r := recover(); r != nil { - t.Logf("Saw EXPECTED panic %v", r) - } else { - t.Errorf("Did not see expected panic") - } - }() - a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} - v := archsimd.LoadInt8x16(a) - e := v.SetElem(seventeen, 18).GetElem(2) - t.Errorf("Should have panicked, e=%v", e) -} - -func TestSlicesInt8SetElem17const(t *testing.T) { - defer func() { - if r := recover(); r != nil { - t.Logf("Saw EXPECTED panic %v", r) - } else { - t.Errorf("Did not see expected panic") - } - }() - a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} - v := archsimd.LoadInt8x16(a) - e := v.SetElem(17, 18).GetElem(2) - t.Errorf("Should have panicked, e=%v", e) -} - func TestSlicesInt8TooShortLoad(t *testing.T) { if !archsimd.X86.AVX2() { t.Skip("Test requires X86.AVX2, not available on this hardware")
diff --git a/src/simd/archsimd/internal/simd_test/simd_test.go b/src/simd/archsimd/internal/simd_test/simd_test.go index 15c13cb..47cf989 100644 --- a/src/simd/archsimd/internal/simd_test/simd_test.go +++ b/src/simd/archsimd/internal/simd_test/simd_test.go
@@ -277,3 +277,103 @@ float64Sink -= a31 float64Sink /= a32 } + +func TestSlicesInt8SetElem(t *testing.T) { + a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32} + v := archsimd.LoadInt8x16(a) + + v = v.SetElem(3, 13) + a[3] = 13 + + b := make([]int8, 16, 16) + v.Store(b) + checkSlices(t, a, b) +} + +func TestSlicesInt8GetElem(t *testing.T) { + a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32} + v := archsimd.LoadInt8x16(a) + e := v.GetElem(2) + if e != a[2] { + t.Errorf("GetElem(2) = %d != a[2] = %d", e, a[2]) + } + +} + +var seventeen = uint8(17) + +func TestSlicesInt8GetElem16(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Logf("Saw EXPECTED panic %v", r) + } else { + t.Errorf("Did not see expected panic") + } + }() + a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + v := archsimd.LoadInt8x16(a) + e := v.GetElem(seventeen - 1) + t.Errorf("Should have panicked, e=%v", e) +} + +func TestSlicesInt8GetElem16const(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Logf("Saw EXPECTED panic %v", r) + } else { + t.Errorf("Did not see expected panic") + } + }() + a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + v := archsimd.LoadInt8x16(a) + e := v.GetElem(16) + t.Errorf("Should have panicked, e=%v", e) +} + +func TestSlicesInt8GetElem15(t *testing.T) { + a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + v := archsimd.LoadInt8x16(a) + e := v.GetElem(seventeen - 2) + if e != a[15] { + t.Errorf("GetElem(15) = %d != a[15] = %d", e, a[15]) + } +} + +func TestSlicesInt8GetElem15const(t *testing.T) { + a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + v := archsimd.LoadInt8x16(a) + e := v.GetElem(15) + if e != a[15] { + t.Errorf("GetElem(15) = %d != a[15] = %d", e, a[15]) + } +} + +func TestSlicesInt8SetElem17(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Logf("Saw EXPECTED panic %v", r) + } else { + t.Errorf("Did not see expected panic") + } + }() + a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + v := archsimd.LoadInt8x16(a) + e := v.SetElem(seventeen, 18).GetElem(2) + t.Errorf("Should have panicked, e=%v", e) +} + +func TestSlicesInt8SetElem17const(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Logf("Saw EXPECTED panic %v", r) + } else { + t.Errorf("Did not see expected panic") + } + }() + a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + v := archsimd.LoadInt8x16(a) + e := v.SetElem(17, 18).GetElem(2) + t.Errorf("Should have panicked, e=%v", e) +}