Commit e6f7a347 authored by Milad Fa's avatar Milad Fa Committed by V8 LUCI CQ

[wasm] fix float to/from int reinterpretation tests

F32ReinterpretI32 and I32ReinterpretF32 tests don't actually have
floating point values involved during testing and only use
integers.

This CL adds FP values as well as fixes the test names to match
their operation.

Change-Id: I321a7f7af8ae93f6eae4fa263f8e8d0b7bf4d672
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3078381Reviewed-by: 's avatarZhi An Ng <zhin@chromium.org>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#76181}
parent f688fe08
......@@ -1053,35 +1053,41 @@ WASM_EXEC_TEST(BrTable_loop_target) {
CHECK_EQ(1, r.Call(0));
}
WASM_EXEC_TEST(F32ReinterpretI32) {
WASM_EXEC_TEST(I32ReinterpretF32) {
WasmRunner<int32_t> r(execution_tier);
int32_t* memory =
r.builder().AddMemoryElems<int32_t>(kWasmPageSize / sizeof(int32_t));
float* memory =
r.builder().AddMemoryElems<float>(kWasmPageSize / sizeof(float));
BUILD(r, WASM_I32_REINTERPRET_F32(
WASM_LOAD_MEM(MachineType::Float32(), WASM_ZERO)));
FOR_INT32_INPUTS(i) {
int32_t expected = i;
r.builder().WriteMemory(&memory[0], expected);
FOR_FLOAT32_INPUTS(i) {
float input = i;
int32_t expected = bit_cast<int32_t, float>(input);
r.builder().WriteMemory(&memory[0], input);
CHECK_EQ(expected, r.Call());
}
}
WASM_EXEC_TEST(I32ReinterpretF32) {
WasmRunner<int32_t, int32_t> r(execution_tier);
WASM_EXEC_TEST(F32ReinterpretI32) {
WasmRunner<float> r(execution_tier);
int32_t* memory =
r.builder().AddMemoryElems<int32_t>(kWasmPageSize / sizeof(int32_t));
BUILD(r,
WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO,
WASM_F32_REINTERPRET_I32(WASM_LOCAL_GET(0))),
WASM_I32V_2(107));
BUILD(r, WASM_F32_REINTERPRET_I32(
WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)));
FOR_INT32_INPUTS(i) {
int32_t expected = i;
CHECK_EQ(107, r.Call(expected));
CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
int32_t input = i;
float expected = bit_cast<float, int32_t>(input);
r.builder().WriteMemory(&memory[0], input);
float result = r.Call();
if (std::isnan(expected)) {
CHECK(std::isnan(result));
CHECK(IsSameNan(expected, result));
} else {
CHECK_EQ(expected, result);
}
}
}
......
......@@ -21,6 +21,25 @@ namespace v8 {
namespace internal {
namespace wasm {
// Helper Functions.
bool IsSameNan(float expected, float actual) {
// Sign is non-deterministic.
uint32_t expected_bits = bit_cast<uint32_t>(expected) & ~0x80000000;
uint32_t actual_bits = bit_cast<uint32_t>(actual) & ~0x80000000;
// Some implementations convert signaling NaNs to quiet NaNs.
return (expected_bits == actual_bits) ||
((expected_bits | 0x00400000) == actual_bits);
}
bool IsSameNan(double expected, double actual) {
// Sign is non-deterministic.
uint64_t expected_bits = bit_cast<uint64_t>(expected) & ~0x8000000000000000;
uint64_t actual_bits = bit_cast<uint64_t>(actual) & ~0x8000000000000000;
// Some implementations convert signaling NaNs to quiet NaNs.
return (expected_bits == actual_bits) ||
((expected_bits | 0x0008000000000000) == actual_bits);
}
TestingModuleBuilder::TestingModuleBuilder(
Zone* zone, ManuallyImportedJSFunction* maybe_import,
TestExecutionTier tier, RuntimeExceptionSupport exception_support,
......
......@@ -96,6 +96,10 @@ struct ManuallyImportedJSFunction {
Handle<JSFunction> js_function;
};
// Helper Functions.
bool IsSameNan(float expected, float actual);
bool IsSameNan(double expected, double actual);
// A Wasm module builder. Globals are pre-set, however, memory and code may be
// progressively added by a test. In turn, we piecemeal update the runtime
// objects, i.e. {WasmInstanceObject}, {WasmModuleObject} and, if necessary,
......
......@@ -401,15 +401,6 @@ bool IsExtreme(float x) {
(abs_x < kSmallFloatThreshold || abs_x > kLargeFloatThreshold);
}
bool IsSameNan(float expected, float actual) {
// Sign is non-deterministic.
uint32_t expected_bits = bit_cast<uint32_t>(expected) & ~0x80000000;
uint32_t actual_bits = bit_cast<uint32_t>(actual) & ~0x80000000;
// Some implementations convert signaling NaNs to quiet NaNs.
return (expected_bits == actual_bits) ||
((expected_bits | 0x00400000) == actual_bits);
}
bool IsCanonical(float actual) {
uint32_t actual_bits = bit_cast<uint32_t>(actual);
// Canonical NaN has quiet bit and no payload.
......@@ -574,15 +565,6 @@ bool IsExtreme(double x) {
(abs_x < kSmallFloatThreshold || abs_x > kLargeFloatThreshold);
}
bool IsSameNan(double expected, double actual) {
// Sign is non-deterministic.
uint64_t expected_bits = bit_cast<uint64_t>(expected) & ~0x8000000000000000;
uint64_t actual_bits = bit_cast<uint64_t>(actual) & ~0x8000000000000000;
// Some implementations convert signaling NaNs to quiet NaNs.
return (expected_bits == actual_bits) ||
((expected_bits | 0x0008000000000000) == actual_bits);
}
bool IsCanonical(double actual) {
uint64_t actual_bits = bit_cast<uint64_t>(actual);
// Canonical NaN has quiet bit and no payload.
......
......@@ -139,13 +139,11 @@ bool PlatformCanRepresent(T x) {
// Returns true for very small and very large numbers. We skip these test
// values for the approximation instructions, which don't work at the extremes.
bool IsExtreme(float x);
bool IsSameNan(float expected, float actual);
bool IsCanonical(float actual);
void CheckFloatResult(float x, float y, float expected, float actual,
bool exact = true);
bool IsExtreme(double x);
bool IsSameNan(double expected, double actual);
bool IsCanonical(double actual);
void CheckDoubleResult(double x, double y, double expected, double actual,
bool exact = true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment