diff options
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.cc | 205 |
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 |