Skip to content

Commit

Permalink
test: Add tests for ceil, floor, trunc
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Aug 14, 2020
1 parent 2a9be5e commit 0c96df1
Showing 1 changed file with 76 additions and 0 deletions.
76 changes: 76 additions & 0 deletions test/unittests/execute_floating_point_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,32 @@ class execute_floating_point_types : public testing::Test
FP<T>::nan(1),
};

// The "int only" is the range of the floating-point type of only consecutive integer values.
// (Integer shift is used instead of std::pow() because of the clang compiler bug).
static constexpr auto int_only_begin = T{uint64_t{1} << (L::digits - 1)};
static constexpr auto int_only_end = T{uint64_t{1} << L::digits};

// The list of rounding test cases as pairs (input, expected_trunc) with only positive inputs.
inline static const std::pair<T, T> positive_trunc_tests[] = {
{0, 0},
{L::denorm_min(), 0},
{L::min(), 0},
{std::nextafter(T{1}, T{0}), T{0}},
{T{1}, T{1}},
{std::nextafter(T{1}, T{2}), T{1}},
{std::nextafter(T{2}, T{1}), T{1}},
{T{2}, T{2}},
{int_only_begin - T{1}, int_only_begin - T{1}},
{int_only_begin - T{0.5}, int_only_begin - T{1}},
{int_only_begin, int_only_begin},
{int_only_begin + T{1}, int_only_begin + T{1}},
{int_only_end - T{1}, int_only_end - T{1}},
{int_only_end, int_only_end},
{int_only_end + T{2}, int_only_end + T{2}},
{L::max(), L::max()},
{L::infinity(), L::infinity()},
};

/// Creates a wasm module with a single function for the given instructions opcode.
/// The opcode is converted to match the type, e.g. f32_add -> f64_add.
static bytes get_numeric_instruction_code(
Expand Down Expand Up @@ -244,6 +270,9 @@ TYPED_TEST(execute_floating_point_types, unop_nan_propagation)
// The list of instructions to be tested.
// Only f32 variants, but f64 variants are going to be covered as well.
constexpr Instr opcodes[] = {
Instr::f32_ceil,
Instr::f32_floor,
Instr::f32_trunc,
Instr::f32_sqrt,
};

Expand Down Expand Up @@ -438,6 +467,53 @@ TYPED_TEST(execute_floating_point_types, neg)
}
}

TYPED_TEST(execute_floating_point_types, ceil)
{
auto instance = instantiate(parse(this->get_unop_code(Instr::f32_ceil)));
const auto exec = [&](auto arg) { return execute(*instance, 0, {arg}); };

for (const auto& [arg, expected_trunc] : this->positive_trunc_tests)
{
// For positive values, the ceil() is trunc() + 1, unless the input is already an integer.
const auto expected_pos =
(arg == expected_trunc) ? expected_trunc : expected_trunc + TypeParam{1};
EXPECT_THAT(exec(arg), Result(expected_pos)) << arg << ": " << expected_pos;

// For negative values, the ceil() is trunc().
EXPECT_THAT(exec(-arg), Result(-expected_trunc)) << -arg << ": " << -expected_trunc;
}
}

TYPED_TEST(execute_floating_point_types, floor)
{
auto instance = instantiate(parse(this->get_unop_code(Instr::f32_floor)));
const auto exec = [&](auto arg) { return execute(*instance, 0, {arg}); };

for (const auto& [arg, expected_trunc] : this->positive_trunc_tests)
{
// For positive values, the floor() is trunc().
EXPECT_THAT(exec(arg), Result(expected_trunc)) << arg << ": " << expected_trunc;

// For negative values, the floor() is trunc() - 1, unless the input is already an integer.
const auto expected_neg =
(arg == expected_trunc) ? -expected_trunc : -expected_trunc - TypeParam{1};
EXPECT_THAT(exec(-arg), Result(expected_neg)) << -arg << ": " << expected_neg;
}
}

TYPED_TEST(execute_floating_point_types, trunc)
{
auto instance = instantiate(parse(this->get_unop_code(Instr::f32_trunc)));
const auto exec = [&](auto arg) { return execute(*instance, 0, {arg}); };

for (const auto& [arg, expected] : this->positive_trunc_tests)
{
EXPECT_THAT(exec(arg), Result(expected)) << arg << ": " << expected;
EXPECT_THAT(exec(-arg), Result(-expected)) << -arg << ": " << -expected;
}
}


TYPED_TEST(execute_floating_point_types, sqrt)
{
using FP = FP<TypeParam>;
Expand Down

0 comments on commit 0c96df1

Please sign in to comment.