Index: test/cctest/wasm/test-run-wasm-simd.cc |
diff --git a/test/cctest/wasm/test-run-wasm-simd.cc b/test/cctest/wasm/test-run-wasm-simd.cc |
index b9a9c8cb32665016b65295633b458bdd8cf8582e..7f36e213e0576e81d8cbe2e4c69e92e5522bff16 100644 |
--- a/test/cctest/wasm/test-run-wasm-simd.cc |
+++ b/test/cctest/wasm/test-run-wasm-simd.cc |
@@ -393,6 +393,20 @@ T RecipSqrt(T a) { |
#define WASM_SIMD_I8x16_REPLACE_LANE(lane, x, y) \ |
x, y, WASM_SIMD_OP(kExprI8x16ReplaceLane), TO_BYTE(lane) |
+#define WASM_SIMD_S32x4_SHUFFLE_OP(opcode, m, x, y) \ |
+ x, y, WASM_SIMD_OP(opcode), TO_BYTE(m[0]), TO_BYTE(m[1]), TO_BYTE(m[2]), \ |
+ TO_BYTE(m[3]) |
+#define WASM_SIMD_S16x8_SHUFFLE_OP(opcode, m, x, y) \ |
+ x, y, WASM_SIMD_OP(opcode), TO_BYTE(m[0]), TO_BYTE(m[1]), TO_BYTE(m[2]), \ |
+ TO_BYTE(m[3]), TO_BYTE(m[4]), TO_BYTE(m[5]), TO_BYTE(m[6]), \ |
+ TO_BYTE(m[7]) |
+#define WASM_SIMD_S8x16_SHUFFLE_OP(opcode, m, x, y) \ |
+ x, y, WASM_SIMD_OP(opcode), TO_BYTE(m[0]), TO_BYTE(m[1]), TO_BYTE(m[2]), \ |
+ TO_BYTE(m[3]), TO_BYTE(m[4]), TO_BYTE(m[5]), TO_BYTE(m[6]), \ |
+ TO_BYTE(m[7]), TO_BYTE(m[8]), TO_BYTE(m[9]), TO_BYTE(m[10]), \ |
+ TO_BYTE(m[11]), TO_BYTE(m[12]), TO_BYTE(m[13]), TO_BYTE(m[14]), \ |
+ TO_BYTE(m[15]) |
+ |
// Skip FP tests involving extremely large or extremely small values, which |
// may fail due to non-IEEE-754 SIMD arithmetic on some platforms. |
bool SkipFPValue(float x) { |
@@ -1570,57 +1584,6 @@ WASM_SIMD_SELECT_TEST(16x8) |
WASM_SIMD_SELECT_TEST(8x16) |
#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 |
-#if V8_TARGET_ARCH_ARM |
-// Test unary ops with a lane test pattern, all lanes distinct. |
-template <typename T> |
-void RunUnaryLaneOpTest( |
- WasmOpcode simd_op, |
- const std::array<T, kSimd128Size / sizeof(T)>& expected) { |
- FLAG_wasm_simd_prototype = true; |
- WasmRunner<int32_t> r(kExecuteCompiled); |
- // Set up a test pattern as a global, e.g. [0, 1, 2, 3]. |
- T* global = r.module().AddGlobal<T>(kWasmS128); |
- static const size_t kElems = kSimd128Size / sizeof(T); |
- for (size_t i = 0; i < kElems; i++) { |
- global[i] = i; |
- } |
- BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_UNOP(simd_op, WASM_GET_GLOBAL(0))), |
- WASM_ONE); |
- |
- CHECK_EQ(1, r.Call()); |
- for (size_t i = 0; i < kElems; i++) { |
- CHECK_EQ(global[i], expected[i]); |
- } |
-} |
- |
-WASM_EXEC_COMPILED_TEST(S32x2Reverse) { |
- RunUnaryLaneOpTest<int32_t>(kExprS32x2Reverse, {{1, 0, 3, 2}}); |
-} |
- |
-WASM_EXEC_COMPILED_TEST(S16x4Reverse) { |
- RunUnaryLaneOpTest<int16_t>(kExprS16x4Reverse, {{3, 2, 1, 0, 7, 6, 5, 4}}); |
-} |
- |
-WASM_EXEC_COMPILED_TEST(S16x2Reverse) { |
- RunUnaryLaneOpTest<int16_t>(kExprS16x2Reverse, {{1, 0, 3, 2, 5, 4, 7, 6}}); |
-} |
- |
-WASM_EXEC_COMPILED_TEST(S8x8Reverse) { |
- RunUnaryLaneOpTest<int8_t>(kExprS8x8Reverse, {{7, 6, 5, 4, 3, 2, 1, 0, 15, 14, |
- 13, 12, 11, 10, 9, 8}}); |
-} |
- |
-WASM_EXEC_COMPILED_TEST(S8x4Reverse) { |
- RunUnaryLaneOpTest<int8_t>(kExprS8x4Reverse, {{3, 2, 1, 0, 7, 6, 5, 4, 11, 10, |
- 9, 8, 15, 14, 13, 12}}); |
-} |
- |
-WASM_EXEC_COMPILED_TEST(S8x2Reverse) { |
- RunUnaryLaneOpTest<int8_t>(kExprS8x2Reverse, {{1, 0, 3, 2, 5, 4, 7, 6, 9, 8, |
- 11, 10, 13, 12, 15, 14}}); |
-} |
-#endif // V8_TARGET_ARCH_ARM |
- |
#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 |
// Test binary ops with two lane test patterns, all lanes distinct. |
template <typename T> |
@@ -1630,21 +1593,50 @@ void RunBinaryLaneOpTest( |
FLAG_wasm_simd_prototype = true; |
WasmRunner<int32_t> r(kExecuteCompiled); |
// Set up two test patterns as globals, e.g. [0, 1, 2, 3] and [4, 5, 6, 7]. |
- T* global1 = r.module().AddGlobal<T>(kWasmS128); |
- T* global2 = r.module().AddGlobal<T>(kWasmS128); |
- static const size_t kElems = kSimd128Size / sizeof(T); |
- for (size_t i = 0; i < kElems; i++) { |
- global1[i] = static_cast<T>(i); |
- global2[i] = static_cast<T>(kElems + i); |
+ T* src0 = r.module().AddGlobal<T>(kWasmS128); |
+ T* src1 = r.module().AddGlobal<T>(kWasmS128); |
+ static const int kElems = kSimd128Size / sizeof(T); |
+ for (int i = 0; i < kElems; i++) { |
+ src0[i] = i; |
+ src1[i] = kElems + i; |
+ } |
+ switch (simd_op) { |
+ case kExprS32x4Shuffle: { |
+ BUILD(r, |
+ WASM_SET_GLOBAL(0, WASM_SIMD_S32x4_SHUFFLE_OP(simd_op, expected, |
+ WASM_GET_GLOBAL(0), |
+ WASM_GET_GLOBAL(1))), |
+ WASM_ONE); |
+ break; |
+ } |
+ case kExprS16x8Shuffle: { |
+ BUILD(r, |
+ WASM_SET_GLOBAL(0, WASM_SIMD_S16x8_SHUFFLE_OP(simd_op, expected, |
+ WASM_GET_GLOBAL(0), |
+ WASM_GET_GLOBAL(1))), |
+ WASM_ONE); |
+ break; |
+ } |
+ case kExprS8x16Shuffle: { |
+ BUILD(r, |
+ WASM_SET_GLOBAL(0, WASM_SIMD_S8x16_SHUFFLE_OP(simd_op, expected, |
+ WASM_GET_GLOBAL(0), |
+ WASM_GET_GLOBAL(1))), |
+ WASM_ONE); |
+ break; |
+ } |
+ default: { |
+ BUILD(r, |
+ WASM_SET_GLOBAL(0, WASM_SIMD_BINOP(simd_op, WASM_GET_GLOBAL(0), |
+ WASM_GET_GLOBAL(1))), |
+ WASM_ONE); |
+ break; |
+ } |
} |
- BUILD(r, |
- WASM_SET_GLOBAL(0, WASM_SIMD_BINOP(simd_op, WASM_GET_GLOBAL(0), |
- WASM_GET_GLOBAL(1))), |
- WASM_ONE); |
CHECK_EQ(1, r.Call()); |
for (size_t i = 0; i < expected.size(); i++) { |
- CHECK_EQ(global1[i], expected[i]); |
+ CHECK_EQ(src0[i], expected[i]); |
} |
} |
@@ -1663,136 +1655,181 @@ WASM_EXEC_COMPILED_TEST(F32x4AddHoriz) { |
RunBinaryLaneOpTest<float>(kExprF32x4AddHoriz, {{1.0f, 5.0f, 9.0f, 13.0f}}); |
} |
+// Test some regular shuffles that may have special handling on some targets. |
+// Test a normal and unary versions (where second operand isn't used). |
WASM_EXEC_COMPILED_TEST(S32x4ZipLeft) { |
- RunBinaryLaneOpTest<int32_t>(kExprS32x4ZipLeft, {{0, 4, 1, 5}}); |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{0, 4, 1, 5}}); |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{0, 0, 1, 1}}); |
} |
WASM_EXEC_COMPILED_TEST(S32x4ZipRight) { |
- RunBinaryLaneOpTest<int32_t>(kExprS32x4ZipRight, {{2, 6, 3, 7}}); |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{2, 6, 3, 7}}); |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{2, 2, 3, 3}}); |
} |
WASM_EXEC_COMPILED_TEST(S32x4UnzipLeft) { |
- RunBinaryLaneOpTest<int32_t>(kExprS32x4UnzipLeft, {{0, 2, 4, 6}}); |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{0, 2, 4, 6}}); |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{0, 2, 0, 2}}); |
} |
WASM_EXEC_COMPILED_TEST(S32x4UnzipRight) { |
- RunBinaryLaneOpTest<int32_t>(kExprS32x4UnzipRight, {{1, 3, 5, 7}}); |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{1, 3, 5, 7}}); |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{1, 3, 1, 3}}); |
} |
WASM_EXEC_COMPILED_TEST(S32x4TransposeLeft) { |
- RunBinaryLaneOpTest<int32_t>(kExprS32x4TransposeLeft, {{0, 4, 2, 6}}); |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{0, 4, 2, 6}}); |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{0, 0, 2, 2}}); |
} |
WASM_EXEC_COMPILED_TEST(S32x4TransposeRight) { |
- RunBinaryLaneOpTest<int32_t>(kExprS32x4TransposeRight, {{1, 5, 3, 7}}); |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{1, 5, 3, 7}}); |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{1, 1, 3, 3}}); |
+} |
+ |
+// Reverses are only unary. |
+WASM_EXEC_COMPILED_TEST(S32x2Reverse) { |
+ RunBinaryLaneOpTest<int32_t>(kExprS32x4Shuffle, {{1, 0, 3, 2}}); |
} |
WASM_EXEC_COMPILED_TEST(S16x8ZipLeft) { |
- RunBinaryLaneOpTest<int16_t>(kExprS16x8ZipLeft, {{0, 8, 1, 9, 2, 10, 3, 11}}); |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, {{0, 8, 1, 9, 2, 10, 3, 11}}); |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, {{0, 0, 1, 1, 2, 2, 3, 3}}); |
} |
WASM_EXEC_COMPILED_TEST(S16x8ZipRight) { |
- RunBinaryLaneOpTest<int16_t>(kExprS16x8ZipRight, |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, |
{{4, 12, 5, 13, 6, 14, 7, 15}}); |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, {{4, 4, 5, 5, 6, 6, 7, 7}}); |
} |
WASM_EXEC_COMPILED_TEST(S16x8UnzipLeft) { |
- RunBinaryLaneOpTest<int16_t>(kExprS16x8UnzipLeft, |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, |
{{0, 2, 4, 6, 8, 10, 12, 14}}); |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, {{0, 2, 4, 6, 0, 2, 4, 6}}); |
} |
WASM_EXEC_COMPILED_TEST(S16x8UnzipRight) { |
- RunBinaryLaneOpTest<int16_t>(kExprS16x8UnzipRight, |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, |
{{1, 3, 5, 7, 9, 11, 13, 15}}); |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, {{1, 3, 5, 7, 1, 3, 5, 7}}); |
} |
WASM_EXEC_COMPILED_TEST(S16x8TransposeLeft) { |
- RunBinaryLaneOpTest<int16_t>(kExprS16x8TransposeLeft, |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, |
{{0, 8, 2, 10, 4, 12, 6, 14}}); |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, {{0, 0, 2, 2, 4, 4, 6, 6}}); |
} |
WASM_EXEC_COMPILED_TEST(S16x8TransposeRight) { |
- RunBinaryLaneOpTest<int16_t>(kExprS16x8TransposeRight, |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, |
{{1, 9, 3, 11, 5, 13, 7, 15}}); |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, {{1, 1, 3, 3, 5, 5, 7, 7}}); |
+} |
+ |
+WASM_EXEC_COMPILED_TEST(S16x4Reverse) { |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, {{3, 2, 1, 0, 7, 6, 5, 4}}); |
+} |
+ |
+WASM_EXEC_COMPILED_TEST(S16x2Reverse) { |
+ RunBinaryLaneOpTest<int16_t>(kExprS16x8Shuffle, {{1, 0, 3, 2, 5, 4, 7, 6}}); |
} |
WASM_EXEC_COMPILED_TEST(S8x16ZipLeft) { |
RunBinaryLaneOpTest<int8_t>( |
- kExprS8x16ZipLeft, |
+ kExprS8x16Shuffle, |
{{0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}}); |
+ RunBinaryLaneOpTest<int8_t>( |
+ kExprS8x16Shuffle, {{0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}}); |
} |
WASM_EXEC_COMPILED_TEST(S8x16ZipRight) { |
RunBinaryLaneOpTest<int8_t>( |
- kExprS8x16ZipRight, |
+ kExprS8x16Shuffle, |
{{8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31}}); |
+ RunBinaryLaneOpTest<int8_t>( |
+ kExprS8x16Shuffle, |
+ {{8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}}); |
} |
WASM_EXEC_COMPILED_TEST(S8x16UnzipLeft) { |
RunBinaryLaneOpTest<int8_t>( |
- kExprS8x16UnzipLeft, |
+ kExprS8x16Shuffle, |
{{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}}); |
+ RunBinaryLaneOpTest<int8_t>(kExprS8x16Shuffle, {{0, 2, 4, 6, 8, 10, 12, 14, 0, |
+ 2, 4, 6, 8, 10, 12, 14}}); |
} |
WASM_EXEC_COMPILED_TEST(S8x16UnzipRight) { |
RunBinaryLaneOpTest<int8_t>( |
- kExprS8x16UnzipRight, |
+ kExprS8x16Shuffle, |
{{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}}); |
+ RunBinaryLaneOpTest<int8_t>(kExprS8x16Shuffle, {{1, 3, 5, 7, 9, 11, 13, 15, 1, |
+ 3, 5, 7, 9, 11, 13, 15}}); |
} |
WASM_EXEC_COMPILED_TEST(S8x16TransposeLeft) { |
RunBinaryLaneOpTest<int8_t>( |
- kExprS8x16TransposeLeft, |
+ kExprS8x16Shuffle, |
{{0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30}}); |
+ RunBinaryLaneOpTest<int8_t>(kExprS8x16Shuffle, {{0, 0, 2, 2, 4, 4, 6, 6, 8, 8, |
+ 10, 10, 12, 12, 14, 14}}); |
} |
WASM_EXEC_COMPILED_TEST(S8x16TransposeRight) { |
RunBinaryLaneOpTest<int8_t>( |
- kExprS8x16TransposeRight, |
+ kExprS8x16Shuffle, |
{{1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31}}); |
+ RunBinaryLaneOpTest<int8_t>(kExprS8x16Shuffle, {{1, 1, 3, 3, 5, 5, 7, 7, 9, 9, |
+ 11, 11, 13, 13, 15, 15}}); |
} |
-template <typename T> |
-void RunConcatOpTest(WasmOpcode simd_op, int bytes, |
- const std::array<T, kSimd128Size / sizeof(T)>& expected) { |
- FLAG_wasm_simd_prototype = true; |
- WasmRunner<int32_t> r(kExecuteCompiled); |
- // Set up two test patterns as globals, e.g. [0, 1, 2, 3] and [4, 5, 6, 7]. |
- T* global1 = r.module().AddGlobal<T>(kWasmS128); |
- T* global2 = r.module().AddGlobal<T>(kWasmS128); |
- static const size_t kElems = kSimd128Size / sizeof(T); |
- for (size_t i = 0; i < kElems; i++) { |
- global1[i] = i; |
- global2[i] = kElems + i; |
- } |
- BUILD( |
- r, |
- WASM_SET_GLOBAL(0, WASM_SIMD_CONCAT_OP(simd_op, bytes, WASM_GET_GLOBAL(0), |
- WASM_GET_GLOBAL(1))), |
- WASM_ONE); |
+WASM_EXEC_COMPILED_TEST(S8x8Reverse) { |
+ RunBinaryLaneOpTest<int8_t>(kExprS8x16Shuffle, {{7, 6, 5, 4, 3, 2, 1, 0, 15, |
+ 14, 13, 12, 11, 10, 9, 8}}); |
+} |
- CHECK_EQ(1, r.Call()); |
- for (size_t i = 0; i < expected.size(); i++) { |
- CHECK_EQ(global1[i], expected[i]); |
- } |
+WASM_EXEC_COMPILED_TEST(S8x4Reverse) { |
+ RunBinaryLaneOpTest<int8_t>(kExprS8x16Shuffle, {{3, 2, 1, 0, 7, 6, 5, 4, 11, |
+ 10, 9, 8, 15, 14, 13, 12}}); |
} |
-WASM_EXEC_COMPILED_TEST(S8x16Concat) { |
- std::array<int8_t, kSimd128Size> expected; |
- for (int k = 1; k < 16; k++) { |
- int j = 0; |
- // last 16 - k bytes of first vector. |
- for (int i = k; i < kSimd128Size; i++) { |
- expected[j++] = i; |
+WASM_EXEC_COMPILED_TEST(S8x2Reverse) { |
+ RunBinaryLaneOpTest<int8_t>(kExprS8x16Shuffle, {{1, 0, 3, 2, 5, 4, 7, 6, 9, 8, |
+ 11, 10, 13, 12, 15, 14}}); |
+} |
+ |
+// Test shuffles that concatenate the two vectors. |
+template <typename T> |
+void RunConcatOpTest(WasmOpcode simd_op) { |
+ static const int kLanes = kSimd128Size / sizeof(T); |
+ std::array<T, kLanes> expected; |
+ for (int bias = 1; bias < kLanes; bias++) { |
+ int i = 0; |
+ // last kLanes - bias bytes of first vector. |
+ for (int j = bias; j < kLanes; j++) { |
+ expected[i++] = j; |
} |
- // first k bytes of second vector |
- for (int i = 0; i < k; i++) { |
- expected[j++] = i + kSimd128Size; |
+ // first bias lanes of second vector |
+ for (int j = 0; j < bias; j++) { |
+ expected[i++] = j + kLanes; |
} |
- RunConcatOpTest<int8_t>(kExprS8x16Concat, k, expected); |
+ RunBinaryLaneOpTest<T>(simd_op, expected); |
} |
} |
+WASM_EXEC_COMPILED_TEST(S32x4Concat) { |
+ RunConcatOpTest<int32_t>(kExprS32x4Shuffle); |
+} |
+ |
+WASM_EXEC_COMPILED_TEST(S16x8Concat) { |
+ RunConcatOpTest<int16_t>(kExprS16x8Shuffle); |
+} |
+ |
+WASM_EXEC_COMPILED_TEST(S8x16Concat) { |
+ RunConcatOpTest<int8_t>(kExprS8x16Shuffle); |
+} |
+ |
// Boolean unary operations are 'AllTrue' and 'AnyTrue', which return an integer |
// result. Use relational ops on numeric vectors to create the boolean vector |
// test inputs. Test inputs with all true, all false, one true, and one false. |