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)
+}