brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · cb81a79 Raw
96 lines · c
1//===-- Utility class to test different flavors of float mul ----*- C++ -*-===//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_MULTEST_H10#define LLVM_LIBC_TEST_SRC_MATH_MULTEST_H11 12#include "src/stdlib/rand.h"13#include "src/stdlib/srand.h"14#include "test/UnitTest/FEnvSafeTest.h"15#include "test/UnitTest/FPMatcher.h"16#include "test/UnitTest/Test.h"17#include "utils/MPFRWrapper/MPFRUtils.h"18 19namespace mpfr = LIBC_NAMESPACE::testing::mpfr;20 21template <typename OutType, typename InType>22class MulTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {23 24  struct InConstants {25    DECLARE_SPECIAL_CONSTANTS(InType)26  };27 28  using InFPBits = typename InConstants::FPBits;29  using InStorageType = typename InConstants::StorageType;30 31  static constexpr InStorageType IN_MAX_NORMAL_U =32      InFPBits::max_normal().uintval();33  static constexpr InStorageType IN_MIN_NORMAL_U =34      InFPBits::min_normal().uintval();35  static constexpr InStorageType IN_MAX_SUBNORMAL_U =36      InFPBits::max_subnormal().uintval();37  static constexpr InStorageType IN_MIN_SUBNORMAL_U =38      InFPBits::min_subnormal().uintval();39 40  InStorageType get_random_bit_pattern() {41    InStorageType bits{0};42    for (InStorageType i = 0; i < sizeof(InStorageType) / 2; ++i)43      bits = (bits << 2) + static_cast<uint16_t>(LIBC_NAMESPACE::rand());44    return bits;45  }46 47public:48  using MulFunc = OutType (*)(InType, InType);49 50  void test_subnormal_range(MulFunc func) {51    constexpr InStorageType COUNT = 10'001;52    constexpr InStorageType STEP =53        (IN_MAX_SUBNORMAL_U - IN_MIN_SUBNORMAL_U) / COUNT;54    LIBC_NAMESPACE::srand(1);55    for (int signs = 0; signs < 4; signs++) {56      for (InStorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {57        InType x = InFPBits(get_random_bit_pattern()).get_val();58        InType y = InFPBits(v).get_val();59        if ((signs & 1) != 0)60          x = -x;61        if ((signs & 2) != 0)62          y = -y;63        mpfr::BinaryInput<InType> input{x, y};64        EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Mul, input, func(x, y),65                                       0.5);66      }67    }68  }69 70  void test_normal_range(MulFunc func) {71    constexpr InStorageType COUNT = 10'001;72    constexpr InStorageType STEP = (IN_MAX_NORMAL_U - IN_MIN_NORMAL_U) / COUNT;73    LIBC_NAMESPACE::srand(1);74    for (int signs = 0; signs < 4; signs++) {75      for (InStorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {76        InType x = InFPBits(get_random_bit_pattern()).get_val();77        InType y = InFPBits(v).get_val();78        if ((signs & 1) != 0)79          x = -x;80        if ((signs & 2) != 0)81          y = -y;82        mpfr::BinaryInput<InType> input{x, y};83        EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Mul, input, func(x, y),84                                       0.5);85      }86    }87  }88};89 90#define LIST_MUL_TESTS(OutType, InType, func)                                  \91  using LlvmLibcMulTest = MulTest<OutType, InType>;                            \92  TEST_F(LlvmLibcMulTest, SubnormalRange) { test_subnormal_range(&func); }     \93  TEST_F(LlvmLibcMulTest, NormalRange) { test_normal_range(&func); }94 95#endif // LLVM_LIBC_TEST_SRC_MATH_MULTEST_H96