From 0c96df128596b69b729b15357b59c76a12bcf76b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 13 Aug 2020 11:18:10 +0200 Subject: [PATCH] test: Add tests for ceil, floor, trunc --- .../unittests/execute_floating_point_test.cpp | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/test/unittests/execute_floating_point_test.cpp b/test/unittests/execute_floating_point_test.cpp index 9d6a1a813c..229c771213 100644 --- a/test/unittests/execute_floating_point_test.cpp +++ b/test/unittests/execute_floating_point_test.cpp @@ -155,6 +155,32 @@ class execute_floating_point_types : public testing::Test FP::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 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( @@ -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, }; @@ -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;