brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · ff82f68 Raw
174 lines · c
1//===-- Utility class to test different flavors of float div --------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_DIVTEST_H10#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_DIVTEST_H11 12#include "hdr/errno_macros.h"13#include "hdr/fenv_macros.h"14#include "test/UnitTest/FEnvSafeTest.h"15#include "test/UnitTest/FPMatcher.h"16#include "test/UnitTest/RoundingModeUtils.h"17#include "test/UnitTest/Test.h"18 19using LIBC_NAMESPACE::Sign;20 21template <typename OutType, typename InType>22class DivTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {23 24  DECLARE_SPECIAL_CONSTANTS(OutType)25 26  struct InConstants {27    DECLARE_SPECIAL_CONSTANTS(InType)28  };29 30  using InFPBits = typename InConstants::FPBits;31  using InStorageType = typename InConstants::StorageType;32 33  InConstants in;34 35public:36  using DivFunc = OutType (*)(InType, InType);37 38  void test_special_numbers(DivFunc func) {39    EXPECT_FP_IS_NAN(func(in.aNaN, in.aNaN));40    EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(in.sNaN, in.sNaN), FE_INVALID);41 42    InType qnan_42 = InFPBits::quiet_nan(Sign::POS, 0x42).get_val();43    EXPECT_FP_IS_NAN(func(qnan_42, in.zero));44    EXPECT_FP_IS_NAN(func(in.zero, qnan_42));45 46    EXPECT_FP_EQ(inf, func(in.inf, in.zero));47    EXPECT_FP_EQ(neg_inf, func(in.neg_inf, in.zero));48    EXPECT_FP_EQ(neg_inf, func(in.inf, in.neg_zero));49    EXPECT_FP_EQ(inf, func(in.neg_inf, in.neg_zero));50    EXPECT_FP_EQ(zero, func(in.min_normal, in.inf));51    EXPECT_FP_EQ(zero, func(in.zero, in.inf));52    EXPECT_FP_EQ(zero, func(in.neg_zero, in.neg_inf));53    EXPECT_FP_EQ(neg_zero, func(in.min_normal, in.neg_inf));54    EXPECT_FP_EQ(neg_zero, func(in.zero, in.neg_inf));55  }56 57  void test_division_by_zero(DivFunc func) {58    EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(InType(1.0), in.zero), FE_DIVBYZERO);59    EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf, func(InType(-1.0), in.zero),60                                FE_DIVBYZERO);61    EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf, func(InType(1.0), in.neg_zero),62                                FE_DIVBYZERO);63    EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(InType(1.0), in.zero), FE_DIVBYZERO);64  }65 66  void test_invalid_operations(DivFunc func) {67    EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(in.zero, in.zero), FE_INVALID);68    EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(in.neg_zero, in.zero), FE_INVALID);69    EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(in.zero, in.neg_zero), FE_INVALID);70    EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(in.neg_zero, in.neg_zero), FE_INVALID);71 72    EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(in.inf, in.inf), FE_INVALID);73    EXPECT_MATH_ERRNO(EDOM);74    EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(in.neg_inf, in.inf), FE_INVALID);75    EXPECT_MATH_ERRNO(EDOM);76    EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(in.inf, in.neg_inf), FE_INVALID);77    EXPECT_MATH_ERRNO(EDOM);78    EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(in.neg_inf, in.neg_inf), FE_INVALID);79    EXPECT_MATH_ERRNO(EDOM);80  }81 82  void test_range_errors(DivFunc func) {83    using namespace LIBC_NAMESPACE::fputil::testing;84 85    if (ForceRoundingMode r(RoundingMode::Nearest); r.success) {86      EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(in.max_normal, in.min_normal),87                                  FE_OVERFLOW | FE_INEXACT);88      EXPECT_MATH_ERRNO(ERANGE);89      EXPECT_FP_EQ_WITH_EXCEPTION(-inf,90                                  func(in.neg_max_normal, in.min_denormal),91                                  FE_OVERFLOW | FE_INEXACT);92      EXPECT_MATH_ERRNO(ERANGE);93 94      EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.max_normal),95                                  FE_UNDERFLOW | FE_INEXACT);96      EXPECT_MATH_ERRNO(ERANGE);97      EXPECT_FP_EQ_WITH_EXCEPTION(neg_zero,98                                  func(in.neg_min_denormal, in.max_normal),99                                  FE_UNDERFLOW | FE_INEXACT);100      EXPECT_MATH_ERRNO(ERANGE);101    }102 103    if (ForceRoundingMode r(RoundingMode::TowardZero); r.success) {104      EXPECT_FP_EQ_WITH_EXCEPTION(max_normal,105                                  func(in.max_normal, in.min_normal),106                                  FE_OVERFLOW | FE_INEXACT);107      EXPECT_FP_EQ_WITH_EXCEPTION(neg_max_normal,108                                  func(in.neg_max_normal, in.min_denormal),109                                  FE_OVERFLOW | FE_INEXACT);110 111      EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.max_normal),112                                  FE_UNDERFLOW | FE_INEXACT);113      EXPECT_MATH_ERRNO(ERANGE);114      EXPECT_FP_EQ_WITH_EXCEPTION(neg_zero,115                                  func(in.neg_min_denormal, in.max_normal),116                                  FE_UNDERFLOW | FE_INEXACT);117      EXPECT_MATH_ERRNO(ERANGE);118    }119 120    if (ForceRoundingMode r(RoundingMode::Downward); r.success) {121      EXPECT_FP_EQ_WITH_EXCEPTION(max_normal,122                                  func(in.max_normal, in.min_normal),123                                  FE_OVERFLOW | FE_INEXACT);124      EXPECT_FP_EQ_WITH_EXCEPTION(-inf,125                                  func(in.neg_max_normal, in.min_denormal),126                                  FE_OVERFLOW | FE_INEXACT);127      EXPECT_MATH_ERRNO(ERANGE);128 129      EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.max_normal),130                                  FE_UNDERFLOW | FE_INEXACT);131      EXPECT_MATH_ERRNO(ERANGE);132      EXPECT_FP_EQ_WITH_EXCEPTION(neg_min_denormal,133                                  func(in.neg_min_denormal, in.max_normal),134                                  FE_UNDERFLOW | FE_INEXACT);135      EXPECT_MATH_ERRNO(ERANGE);136    }137 138    if (ForceRoundingMode r(RoundingMode::Upward); r.success) {139      EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(in.max_normal, in.min_normal),140                                  FE_OVERFLOW | FE_INEXACT);141      EXPECT_MATH_ERRNO(ERANGE);142      EXPECT_FP_EQ_WITH_EXCEPTION(neg_max_normal,143                                  func(in.neg_max_normal, in.min_denormal),144                                  FE_OVERFLOW | FE_INEXACT);145 146      EXPECT_FP_EQ_WITH_EXCEPTION(min_denormal,147                                  func(in.min_denormal, in.max_normal),148                                  FE_UNDERFLOW | FE_INEXACT);149      EXPECT_MATH_ERRNO(ERANGE);150      EXPECT_FP_EQ_WITH_EXCEPTION(neg_zero,151                                  func(in.neg_min_denormal, in.max_normal),152                                  FE_UNDERFLOW | FE_INEXACT);153      EXPECT_MATH_ERRNO(ERANGE);154    }155  }156 157  void test_inexact_results(DivFunc func) {158    func(InType(1.0), InType(3.0));159    EXPECT_FP_EXCEPTION(FE_INEXACT);160  }161};162 163#define LIST_DIV_TESTS(OutType, InType, func)                                  \164  using LlvmLibcDivTest = DivTest<OutType, InType>;                            \165  TEST_F(LlvmLibcDivTest, SpecialNumbers) { test_special_numbers(&func); }     \166  TEST_F(LlvmLibcDivTest, DivisionByZero) { test_division_by_zero(&func); }    \167  TEST_F(LlvmLibcDivTest, InvalidOperations) {                                 \168    test_invalid_operations(&func);                                            \169  }                                                                            \170  TEST_F(LlvmLibcDivTest, RangeErrors) { test_range_errors(&func); }           \171  TEST_F(LlvmLibcDivTest, InexactResults) { test_inexact_results(&func); }172 173#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_DIVTEST_H174