summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest/wasm/test-run-wasm-simd.cc')
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-simd.cc205
1 files changed, 131 insertions, 74 deletions
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
index b0f3dcf8ce..ed8bdf7281 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <type_traits>
+
#include "src/assembler-inl.h"
#include "src/base/bits.h"
+#include "src/base/overflowing-math.h"
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/value-helper.h"
#include "test/cctest/wasm/wasm-run-utils.h"
@@ -50,22 +53,29 @@ typedef int8_t (*Int8ShiftOp)(int8_t, int);
void RunWasm_##name##_Impl(LowerSimd lower_simd, ExecutionTier execution_tier)
// Generic expected value functions.
-template <typename T>
+template <typename T, typename = typename std::enable_if<
+ std::is_floating_point<T>::value>::type>
T Negate(T a) {
return -a;
}
-template <typename T>
+// For signed integral types, use base::AddWithWraparound.
+template <typename T, typename = typename std::enable_if<
+ std::is_floating_point<T>::value>::type>
T Add(T a, T b) {
return a + b;
}
-template <typename T>
+// For signed integral types, use base::SubWithWraparound.
+template <typename T, typename = typename std::enable_if<
+ std::is_floating_point<T>::value>::type>
T Sub(T a, T b) {
return a - b;
}
-template <typename T>
+// For signed integral types, use base::MulWithWraparound.
+template <typename T, typename = typename std::enable_if<
+ std::is_floating_point<T>::value>::type>
T Mul(T a, T b) {
return a * b;
}
@@ -243,16 +253,6 @@ T Sqrt(T a) {
return std::sqrt(a);
}
-template <typename T>
-T Recip(T a) {
- return 1.0f / a;
-}
-
-template <typename T>
-T RecipSqrt(T a) {
- return 1.0f / std::sqrt(a);
-}
-
} // namespace
#define WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lane_value, lane_index) \
@@ -438,10 +438,36 @@ WASM_SIMD_TEST(F32x4ReplaceLane) {
CHECK_EQ(1, r.Call(3.14159f, -1.5f));
}
-#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
- V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_IA32
+// Runs tests of compiled code, using the interpreter as a reference.
+#define WASM_SIMD_COMPILED_TEST(name) \
+ void RunWasm_##name##_Impl(LowerSimd lower_simd, \
+ ExecutionTier execution_tier); \
+ TEST(RunWasm_##name##_turbofan) { \
+ EXPERIMENTAL_FLAG_SCOPE(simd); \
+ RunWasm_##name##_Impl(kNoLowerSimd, ExecutionTier::kOptimized); \
+ } \
+ TEST(RunWasm_##name##_simd_lowered) { \
+ EXPERIMENTAL_FLAG_SCOPE(simd); \
+ RunWasm_##name##_Impl(kLowerSimd, ExecutionTier::kOptimized); \
+ } \
+ void RunWasm_##name##_Impl(LowerSimd lower_simd, ExecutionTier execution_tier)
+
+// The macro below disables tests lowering for certain nodes where the simd
+// lowering doesn't work correctly. Early return here if the CPU does not
+// support SIMD as the graph will be implicitly lowered in that case.
+#define WASM_SIMD_TEST_TURBOFAN(name) \
+ void RunWasm_##name##_Impl(LowerSimd lower_simd, \
+ ExecutionTier execution_tier); \
+ TEST(RunWasm_##name##_turbofan) { \
+ if (!CpuFeatures::SupportsWasmSimd128()) return; \
+ EXPERIMENTAL_FLAG_SCOPE(simd); \
+ RunWasm_##name##_Impl(kNoLowerSimd, ExecutionTier::kOptimized); \
+ } \
+ void RunWasm_##name##_Impl(LowerSimd lower_simd, ExecutionTier execution_tier)
+
// Tests both signed and unsigned conversion.
-WASM_SIMD_TEST(F32x4ConvertI32x4) {
+// v8:8425 tracks this test being enabled in the interpreter.
+WASM_SIMD_COMPILED_TEST(F32x4ConvertI32x4) {
WasmRunner<int32_t, int32_t, float, float> r(execution_tier, lower_simd);
byte a = 0;
byte expected_signed = 1;
@@ -463,8 +489,6 @@ WASM_SIMD_TEST(F32x4ConvertI32x4) {
static_cast<float>(static_cast<uint32_t>(*i))));
}
}
-#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
- // V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_IA32
void RunF32x4UnOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode simd_op, FloatUnOp expected_op,
@@ -498,13 +522,13 @@ WASM_SIMD_TEST(F32x4Neg) {
static const float kApproxError = 0.01f;
WASM_SIMD_TEST(F32x4RecipApprox) {
- RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4RecipApprox, Recip,
- kApproxError);
+ RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4RecipApprox,
+ base::Recip, kApproxError);
}
WASM_SIMD_TEST(F32x4RecipSqrtApprox) {
RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4RecipSqrtApprox,
- RecipSqrt, kApproxError);
+ base::RecipSqrt, kApproxError);
}
void RunF32x4BinOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
@@ -819,9 +843,6 @@ WASM_SIMD_TEST(I8x16ReplaceLane) {
CHECK_EQ(1, r.Call(1, 2));
}
-#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
- V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_IA32
-
int32_t ConvertToInt(double val, bool unsigned_integer) {
if (std::isnan(val)) return 0;
if (unsigned_integer) {
@@ -900,8 +921,6 @@ WASM_SIMD_TEST(I32x4ConvertI16x8) {
CHECK_EQ(1, r.Call(*i, unpacked_signed, unpacked_unsigned, 0));
}
}
-#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
- // V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_IA32
void RunI32x4UnOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode simd_op, Int32UnOp expected_op) {
@@ -917,7 +936,8 @@ void RunI32x4UnOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
}
WASM_SIMD_TEST(I32x4Neg) {
- RunI32x4UnOpTest(execution_tier, lower_simd, kExprI32x4Neg, Negate);
+ RunI32x4UnOpTest(execution_tier, lower_simd, kExprI32x4Neg,
+ base::NegateWithWraparound);
}
WASM_SIMD_TEST(S128Not) {
@@ -944,15 +964,18 @@ void RunI32x4BinOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
}
WASM_SIMD_TEST(I32x4Add) {
- RunI32x4BinOpTest(execution_tier, lower_simd, kExprI32x4Add, Add);
+ RunI32x4BinOpTest(execution_tier, lower_simd, kExprI32x4Add,
+ base::AddWithWraparound);
}
WASM_SIMD_TEST(I32x4Sub) {
- RunI32x4BinOpTest(execution_tier, lower_simd, kExprI32x4Sub, Sub);
+ RunI32x4BinOpTest(execution_tier, lower_simd, kExprI32x4Sub,
+ base::SubWithWraparound);
}
WASM_SIMD_TEST(I32x4Mul) {
- RunI32x4BinOpTest(execution_tier, lower_simd, kExprI32x4Mul, Mul);
+ RunI32x4BinOpTest(execution_tier, lower_simd, kExprI32x4Mul,
+ base::MulWithWraparound);
}
WASM_SIMD_TEST(I32x4MinS) {
@@ -1137,7 +1160,8 @@ void RunI16x8UnOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
}
WASM_SIMD_TEST(I16x8Neg) {
- RunI16x8UnOpTest(execution_tier, lower_simd, kExprI16x8Neg, Negate);
+ RunI16x8UnOpTest(execution_tier, lower_simd, kExprI16x8Neg,
+ base::NegateWithWraparound);
}
// Tests both signed and unsigned conversion from I32x4 (packing).
@@ -1205,7 +1229,8 @@ void RunI16x8BinOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
}
WASM_SIMD_TEST(I16x8Add) {
- RunI16x8BinOpTest(execution_tier, lower_simd, kExprI16x8Add, Add);
+ RunI16x8BinOpTest(execution_tier, lower_simd, kExprI16x8Add,
+ base::AddWithWraparound);
}
WASM_SIMD_TEST(I16x8AddSaturateS) {
@@ -1214,7 +1239,8 @@ WASM_SIMD_TEST(I16x8AddSaturateS) {
}
WASM_SIMD_TEST(I16x8Sub) {
- RunI16x8BinOpTest(execution_tier, lower_simd, kExprI16x8Sub, Sub);
+ RunI16x8BinOpTest(execution_tier, lower_simd, kExprI16x8Sub,
+ base::SubWithWraparound);
}
WASM_SIMD_TEST(I16x8SubSaturateS) {
@@ -1223,7 +1249,8 @@ WASM_SIMD_TEST(I16x8SubSaturateS) {
}
WASM_SIMD_TEST(I16x8Mul) {
- RunI16x8BinOpTest(execution_tier, lower_simd, kExprI16x8Mul, Mul);
+ RunI16x8BinOpTest(execution_tier, lower_simd, kExprI16x8Mul,
+ base::MulWithWraparound);
}
WASM_SIMD_TEST(I16x8MinS) {
@@ -1363,7 +1390,8 @@ void RunI8x16UnOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
}
WASM_SIMD_TEST(I8x16Neg) {
- RunI8x16UnOpTest(execution_tier, lower_simd, kExprI8x16Neg, Negate);
+ RunI8x16UnOpTest(execution_tier, lower_simd, kExprI8x16Neg,
+ base::NegateWithWraparound);
}
// Tests both signed and unsigned conversion from I16x8 (packing).
@@ -1433,7 +1461,8 @@ void RunI8x16BinOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
}
WASM_SIMD_TEST(I8x16Add) {
- RunI8x16BinOpTest(execution_tier, lower_simd, kExprI8x16Add, Add);
+ RunI8x16BinOpTest(execution_tier, lower_simd, kExprI8x16Add,
+ base::AddWithWraparound);
}
WASM_SIMD_TEST(I8x16AddSaturateS) {
@@ -1442,7 +1471,8 @@ WASM_SIMD_TEST(I8x16AddSaturateS) {
}
WASM_SIMD_TEST(I8x16Sub) {
- RunI8x16BinOpTest(execution_tier, lower_simd, kExprI8x16Sub, Sub);
+ RunI8x16BinOpTest(execution_tier, lower_simd, kExprI8x16Sub,
+ base::SubWithWraparound);
}
WASM_SIMD_TEST(I8x16SubSaturateS) {
@@ -1542,13 +1572,10 @@ WASM_SIMD_TEST(I8x16LeU) {
UnsignedLessEqual);
}
-#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
- V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_IA32
WASM_SIMD_TEST(I8x16Mul) {
- RunI8x16BinOpTest(execution_tier, lower_simd, kExprI8x16Mul, Mul);
+ RunI8x16BinOpTest(execution_tier, lower_simd, kExprI8x16Mul,
+ base::MulWithWraparound);
}
-#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
- // V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_IA32
void RunI8x16ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode simd_op, Int8ShiftOp expected_op) {
@@ -1566,8 +1593,6 @@ void RunI8x16ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
}
}
-#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
- V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_IA32
WASM_SIMD_TEST(I8x16Shl) {
RunI8x16ShiftOpTest(execution_tier, lower_simd, kExprI8x16Shl,
LogicalShiftLeft);
@@ -1582,14 +1607,12 @@ WASM_SIMD_TEST(I8x16ShrU) {
RunI8x16ShiftOpTest(execution_tier, lower_simd, kExprI8x16ShrU,
LogicalShiftRight);
}
-#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
- // V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_IA32
// Test Select by making a mask where the 0th and 3rd lanes are true and the
// rest false, and comparing for non-equality with zero to convert to a boolean
// vector.
#define WASM_SIMD_SELECT_TEST(format) \
- WASM_SIMD_TEST(S##format##Select) { \
+ WASM_SIMD_TEST_TURBOFAN(S##format##Select) { \
WasmRunner<int32_t, int32_t, int32_t> r(execution_tier, lower_simd); \
byte val1 = 0; \
byte val2 = 1; \
@@ -1610,10 +1633,9 @@ WASM_SIMD_TEST(I8x16ShrU) {
WASM_SET_LOCAL( \
mask, \
WASM_SIMD_SELECT( \
- format, \
+ format, WASM_GET_LOCAL(src1), WASM_GET_LOCAL(src2), \
WASM_SIMD_BINOP(kExprI##format##Ne, WASM_GET_LOCAL(mask), \
- WASM_GET_LOCAL(zero)), \
- WASM_GET_LOCAL(src1), WASM_GET_LOCAL(src2))), \
+ WASM_GET_LOCAL(zero)))), \
WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 0), \
WASM_SIMD_CHECK_LANE(I##format, mask, I32, val1, 1), \
WASM_SIMD_CHECK_LANE(I##format, mask, I32, val1, 2), \
@@ -1629,7 +1651,7 @@ WASM_SIMD_SELECT_TEST(8x16)
// Test Select by making a mask where the 0th and 3rd lanes are non-zero and the
// rest 0. The mask is not the result of a comparison op.
#define WASM_SIMD_NON_CANONICAL_SELECT_TEST(format) \
- WASM_SIMD_TEST(S##format##NonCanonicalSelect) { \
+ WASM_SIMD_TEST_TURBOFAN(S##format##NonCanonicalSelect) { \
WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_tier, \
lower_simd); \
byte val1 = 0; \
@@ -1649,9 +1671,9 @@ WASM_SIMD_SELECT_TEST(8x16)
1, WASM_GET_LOCAL(zero), WASM_I32V(0xF))), \
WASM_SET_LOCAL(mask, WASM_SIMD_I##format##_REPLACE_LANE( \
2, WASM_GET_LOCAL(mask), WASM_I32V(0xF))), \
- WASM_SET_LOCAL(mask, WASM_SIMD_SELECT(format, WASM_GET_LOCAL(mask), \
- WASM_GET_LOCAL(src1), \
- WASM_GET_LOCAL(src2))), \
+ WASM_SET_LOCAL(mask, WASM_SIMD_SELECT(format, WASM_GET_LOCAL(src1), \
+ WASM_GET_LOCAL(src2), \
+ WASM_GET_LOCAL(mask))), \
WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 0), \
WASM_SIMD_CHECK_LANE(I##format, mask, I32, combined, 1), \
WASM_SIMD_CHECK_LANE(I##format, mask, I32, combined, 2), \
@@ -1740,8 +1762,6 @@ void RunShuffleOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
other_swizzle);
}
-#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
- V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_IA32
#define SHUFFLE_LIST(V) \
V(S128Identity) \
V(S32x4Dup) \
@@ -1939,20 +1959,6 @@ void BuildShuffle(std::vector<Shuffle>& shuffles, std::vector<byte>* buffer) {
for (size_t j = 0; j < arraysize(epilog); ++j) buffer->push_back(epilog[j]);
}
-// Runs tests of compiled code, using the interpreter as a reference.
-#define WASM_SIMD_COMPILED_TEST(name) \
- void RunWasm_##name##_Impl(LowerSimd lower_simd, \
- ExecutionTier execution_tier); \
- TEST(RunWasm_##name##_turbofan) { \
- EXPERIMENTAL_FLAG_SCOPE(simd); \
- RunWasm_##name##_Impl(kNoLowerSimd, ExecutionTier::kOptimized); \
- } \
- TEST(RunWasm_##name##_simd_lowered) { \
- EXPERIMENTAL_FLAG_SCOPE(simd); \
- RunWasm_##name##_Impl(kLowerSimd, ExecutionTier::kOptimized); \
- } \
- void RunWasm_##name##_Impl(LowerSimd lower_simd, ExecutionTier execution_tier)
-
void RunWasmCode(ExecutionTier execution_tier, LowerSimd lower_simd,
const std::vector<byte>& code,
std::array<int8_t, kSimd128Size>* result) {
@@ -2000,8 +2006,6 @@ WASM_SIMD_COMPILED_TEST(S8x16MultiShuffleFuzz) {
}
}
}
-#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
- // V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_IA32
// Boolean unary operations are 'AllTrue' and 'AnyTrue', which return an integer
// result. Use relational ops on numeric vectors to create the boolean vector
@@ -2320,7 +2324,7 @@ WASM_SIMD_TEST(SimdF32x4SetGlobal) {
CHECK_EQ(GetScalar(global, 3), 65.0f);
}
-WASM_SIMD_TEST(SimdLoadStoreLoad) {
+WASM_SIMD_COMPILED_TEST(SimdLoadStoreLoad) {
WasmRunner<int32_t> r(execution_tier, lower_simd);
int32_t* memory =
r.builder().AddMemoryElems<int32_t>(kWasmPageSize / sizeof(int32_t));
@@ -2336,6 +2340,56 @@ WASM_SIMD_TEST(SimdLoadStoreLoad) {
}
}
+#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32
+// V8:8665 - Tracking bug to enable reduction tests in the interpreter,
+// and for SIMD lowering.
+// TODO(gdeepti): Enable these tests for ARM/ARM64
+#define WASM_SIMD_ANYTRUE_TEST(format, lanes, max) \
+ WASM_SIMD_TEST_TURBOFAN(S##format##AnyTrue) { \
+ WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); \
+ byte simd = r.AllocateLocal(kWasmS128); \
+ BUILD( \
+ r, \
+ WASM_SET_LOCAL(simd, WASM_SIMD_I##format##_SPLAT(WASM_GET_LOCAL(0))), \
+ WASM_SIMD_UNOP(kExprS1x##lanes##AnyTrue, WASM_GET_LOCAL(simd))); \
+ DCHECK_EQ(1, r.Call(max)); \
+ DCHECK_EQ(1, r.Call(5)); \
+ DCHECK_EQ(0, r.Call(0)); \
+ }
+WASM_SIMD_ANYTRUE_TEST(32x4, 4, 0xffffffff);
+WASM_SIMD_ANYTRUE_TEST(16x8, 8, 0xffff);
+WASM_SIMD_ANYTRUE_TEST(8x16, 16, 0xff);
+
+#define WASM_SIMD_ALLTRUE_TEST(format, lanes, max) \
+ WASM_SIMD_TEST_TURBOFAN(S##format##AllTrue) { \
+ WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); \
+ byte simd = r.AllocateLocal(kWasmS128); \
+ BUILD( \
+ r, \
+ WASM_SET_LOCAL(simd, WASM_SIMD_I##format##_SPLAT(WASM_GET_LOCAL(0))), \
+ WASM_SIMD_UNOP(kExprS1x##lanes##AllTrue, WASM_GET_LOCAL(simd))); \
+ DCHECK_EQ(1, r.Call(max)); \
+ DCHECK_EQ(0, r.Call(21)); \
+ DCHECK_EQ(0, r.Call(0)); \
+ }
+WASM_SIMD_ALLTRUE_TEST(32x4, 4, 0xffffffff);
+WASM_SIMD_ALLTRUE_TEST(16x8, 8, 0xffff);
+WASM_SIMD_ALLTRUE_TEST(8x16, 16, 0xff);
+#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32
+
+WASM_SIMD_TEST_TURBOFAN(BitSelect) {
+ WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
+ byte simd = r.AllocateLocal(kWasmS128);
+ BUILD(r,
+ WASM_SET_LOCAL(
+ simd,
+ WASM_SIMD_SELECT(32x4, WASM_SIMD_I32x4_SPLAT(WASM_I32V(0x01020304)),
+ WASM_SIMD_I32x4_SPLAT(WASM_I32V(0)),
+ WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(0)))),
+ WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(simd)));
+ DCHECK_EQ(0x01020304, r.Call(0xFFFFFFFF));
+}
+
#undef WASM_SIMD_TEST
#undef WASM_SIMD_CHECK_LANE
#undef WASM_SIMD_CHECK4
@@ -2376,6 +2430,9 @@ WASM_SIMD_TEST(SimdLoadStoreLoad) {
#undef WASM_SIMD_NON_CANONICAL_SELECT_TEST
#undef WASM_SIMD_COMPILED_TEST
#undef WASM_SIMD_BOOL_REDUCTION_TEST
+#undef WASM_SIMD_TEST_TURBOFAN
+#undef WASM_SIMD_ANYTRUE_TEST
+#undef WASM_SIMD_ALLTRUE_TEST
} // namespace test_run_wasm_simd
} // namespace wasm