262 lines · c
1//===-- Utility class to test fmod special numbers ------------------------===//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_FMODTEST_H10#define LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H11 12#include "hdr/errno_macros.h"13#include "src/__support/FPUtil/FEnvImpl.h"14#include "test/UnitTest/FEnvSafeTest.h"15#include "test/UnitTest/FPMatcher.h"16#include "test/UnitTest/Test.h"17 18#include "hdr/fenv_macros.h"19 20#define TEST_SPECIAL(x, y, expected, dom_err, expected_exception) \21 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); \22 EXPECT_FP_EQ(expected, f(x, y)); \23 EXPECT_MATH_ERRNO((dom_err) ? EDOM : 0); \24 EXPECT_FP_EXCEPTION(expected_exception); \25 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT)26 27#define TEST_REGULAR(x, y, expected) TEST_SPECIAL(x, y, expected, false, 0)28 29template <typename T>30class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {31 32 DECLARE_SPECIAL_CONSTANTS(T)33 34 static constexpr T one = T(1.0);35 static constexpr T two = T(2.0);36 static constexpr T neg_two = T(-2.0);37 static constexpr T three = T(3.0);38 static constexpr T val_neg_1_1 = T(-1.1);39 static constexpr T val_6_5 = T(6.5);40 static constexpr T val_neg_6_5 = T(-6.5);41 static constexpr T val_2_25 = T(2.25);42 static constexpr T val_neg_2_25 = T(-2.25);43 44public:45 typedef T (*FModFunc)(T, T);46 47 void testSpecialNumbers(FModFunc f) {48 // fmod (+0, y) == +0 for y != 0.49 TEST_SPECIAL(zero, three, zero, false, 0);50 TEST_SPECIAL(zero, min_denormal, zero, false, 0);51 TEST_SPECIAL(zero, -min_denormal, zero, false, 0);52 TEST_SPECIAL(zero, min_normal, zero, false, 0);53 TEST_SPECIAL(zero, -min_normal, zero, false, 0);54 TEST_SPECIAL(zero, max_normal, zero, false, 0);55 TEST_SPECIAL(zero, -max_normal, zero, false, 0);56 57 // fmod (-0, y) == -0 for y != 0.58 TEST_SPECIAL(neg_zero, three, neg_zero, false, 0);59 TEST_SPECIAL(neg_zero, min_denormal, neg_zero, false, 0);60 TEST_SPECIAL(neg_zero, -min_denormal, neg_zero, false, 0);61 TEST_SPECIAL(neg_zero, min_normal, neg_zero, false, 0);62 TEST_SPECIAL(neg_zero, -min_normal, neg_zero, false, 0);63 TEST_SPECIAL(neg_zero, max_normal, neg_zero, false, 0);64 TEST_SPECIAL(neg_zero, -max_normal, neg_zero, false, 0);65 66 // fmod (+inf, y) == aNaN plus invalid exception.67 TEST_SPECIAL(inf, three, aNaN, true, FE_INVALID);68 TEST_SPECIAL(inf, val_neg_1_1, aNaN, true, FE_INVALID);69 TEST_SPECIAL(inf, zero, aNaN, true, FE_INVALID);70 TEST_SPECIAL(inf, neg_zero, aNaN, true, FE_INVALID);71 TEST_SPECIAL(inf, min_denormal, aNaN, true, FE_INVALID);72 TEST_SPECIAL(inf, min_normal, aNaN, true, FE_INVALID);73 TEST_SPECIAL(inf, max_normal, aNaN, true, FE_INVALID);74 TEST_SPECIAL(inf, inf, aNaN, true, FE_INVALID);75 TEST_SPECIAL(inf, neg_inf, aNaN, true, FE_INVALID);76 77 // fmod (-inf, y) == aNaN plus invalid exception.78 TEST_SPECIAL(neg_inf, three, aNaN, true, FE_INVALID);79 TEST_SPECIAL(neg_inf, val_neg_1_1, aNaN, true, FE_INVALID);80 TEST_SPECIAL(neg_inf, zero, aNaN, true, FE_INVALID);81 TEST_SPECIAL(neg_inf, neg_zero, aNaN, true, FE_INVALID);82 TEST_SPECIAL(neg_inf, min_denormal, aNaN, true, FE_INVALID);83 TEST_SPECIAL(neg_inf, min_normal, aNaN, true, FE_INVALID);84 TEST_SPECIAL(neg_inf, max_normal, aNaN, true, FE_INVALID);85 TEST_SPECIAL(neg_inf, inf, aNaN, true, FE_INVALID);86 TEST_SPECIAL(neg_inf, neg_inf, aNaN, true, FE_INVALID);87 88 // fmod (x, +0) == aNaN plus invalid exception.89 TEST_SPECIAL(three, zero, aNaN, true, FE_INVALID);90 TEST_SPECIAL(val_neg_1_1, zero, aNaN, true, FE_INVALID);91 TEST_SPECIAL(zero, zero, aNaN, true, FE_INVALID);92 TEST_SPECIAL(neg_zero, zero, aNaN, true, FE_INVALID);93 TEST_SPECIAL(min_denormal, zero, aNaN, true, FE_INVALID);94 TEST_SPECIAL(min_normal, zero, aNaN, true, FE_INVALID);95 TEST_SPECIAL(max_normal, zero, aNaN, true, FE_INVALID);96 97 // fmod (x, -0) == aNaN plus invalid exception.98 TEST_SPECIAL(three, neg_zero, aNaN, true, FE_INVALID);99 TEST_SPECIAL(val_neg_1_1, neg_zero, aNaN, true, FE_INVALID);100 TEST_SPECIAL(zero, neg_zero, aNaN, true, FE_INVALID);101 TEST_SPECIAL(neg_zero, neg_zero, aNaN, true, FE_INVALID);102 TEST_SPECIAL(min_denormal, neg_zero, aNaN, true, FE_INVALID);103 TEST_SPECIAL(min_normal, neg_zero, aNaN, true, FE_INVALID);104 TEST_SPECIAL(max_normal, neg_zero, aNaN, true, FE_INVALID);105 106 // fmod (x, +inf) == x for x not infinite.107 TEST_SPECIAL(zero, inf, zero, false, 0);108 TEST_SPECIAL(neg_zero, inf, neg_zero, false, 0);109 TEST_SPECIAL(min_denormal, inf, min_denormal, false, 0);110 TEST_SPECIAL(min_normal, inf, min_normal, false, 0);111 TEST_SPECIAL(max_normal, inf, max_normal, false, 0);112 TEST_SPECIAL(three, inf, three, false, 0);113 // fmod (x, -inf) == x for x not infinite.114 TEST_SPECIAL(zero, neg_inf, zero, false, 0);115 TEST_SPECIAL(neg_zero, neg_inf, neg_zero, false, 0);116 TEST_SPECIAL(min_denormal, neg_inf, min_denormal, false, 0);117 TEST_SPECIAL(min_normal, neg_inf, min_normal, false, 0);118 TEST_SPECIAL(max_normal, neg_inf, max_normal, false, 0);119 TEST_SPECIAL(three, neg_inf, three, false, 0);120 121 TEST_SPECIAL(zero, aNaN, aNaN, false, 0);122 TEST_SPECIAL(zero, neg_aNaN, aNaN, false, 0);123 TEST_SPECIAL(neg_zero, aNaN, aNaN, false, 0);124 TEST_SPECIAL(neg_zero, neg_aNaN, aNaN, false, 0);125 TEST_SPECIAL(one, aNaN, aNaN, false, 0);126 TEST_SPECIAL(one, neg_aNaN, aNaN, false, 0);127 TEST_SPECIAL(inf, aNaN, aNaN, false, 0);128 TEST_SPECIAL(inf, neg_aNaN, aNaN, false, 0);129 TEST_SPECIAL(neg_inf, aNaN, aNaN, false, 0);130 TEST_SPECIAL(neg_inf, neg_aNaN, aNaN, false, 0);131 TEST_SPECIAL(zero, sNaN, aNaN, false, FE_INVALID);132 TEST_SPECIAL(zero, neg_sNaN, aNaN, false, FE_INVALID);133 TEST_SPECIAL(neg_zero, sNaN, aNaN, false, FE_INVALID);134 TEST_SPECIAL(neg_zero, neg_sNaN, aNaN, false, FE_INVALID);135 TEST_SPECIAL(one, sNaN, aNaN, false, FE_INVALID);136 TEST_SPECIAL(one, neg_sNaN, aNaN, false, FE_INVALID);137 TEST_SPECIAL(inf, sNaN, aNaN, false, FE_INVALID);138 TEST_SPECIAL(inf, neg_sNaN, aNaN, false, FE_INVALID);139 TEST_SPECIAL(neg_inf, sNaN, aNaN, false, FE_INVALID);140 TEST_SPECIAL(neg_inf, neg_sNaN, aNaN, false, FE_INVALID);141 TEST_SPECIAL(aNaN, zero, aNaN, false, 0);142 TEST_SPECIAL(neg_aNaN, zero, aNaN, false, 0);143 TEST_SPECIAL(aNaN, neg_zero, aNaN, false, 0);144 TEST_SPECIAL(neg_aNaN, neg_zero, aNaN, false, 0);145 TEST_SPECIAL(aNaN, one, aNaN, false, 0);146 TEST_SPECIAL(neg_aNaN, one, aNaN, false, 0);147 TEST_SPECIAL(aNaN, inf, aNaN, false, 0);148 TEST_SPECIAL(neg_aNaN, inf, aNaN, false, 0);149 TEST_SPECIAL(aNaN, neg_inf, aNaN, false, 0);150 TEST_SPECIAL(neg_aNaN, neg_inf, aNaN, false, 0);151 TEST_SPECIAL(sNaN, zero, aNaN, false, FE_INVALID);152 TEST_SPECIAL(neg_sNaN, zero, aNaN, false, FE_INVALID);153 TEST_SPECIAL(sNaN, neg_zero, aNaN, false, FE_INVALID);154 TEST_SPECIAL(neg_sNaN, neg_zero, aNaN, false, FE_INVALID);155 TEST_SPECIAL(sNaN, one, aNaN, false, FE_INVALID);156 TEST_SPECIAL(neg_sNaN, one, aNaN, false, FE_INVALID);157 TEST_SPECIAL(sNaN, inf, aNaN, false, FE_INVALID);158 TEST_SPECIAL(neg_sNaN, inf, aNaN, false, FE_INVALID);159 TEST_SPECIAL(sNaN, neg_inf, aNaN, false, FE_INVALID);160 TEST_SPECIAL(neg_sNaN, neg_inf, aNaN, false, FE_INVALID);161 TEST_SPECIAL(aNaN, aNaN, aNaN, false, 0);162 TEST_SPECIAL(aNaN, neg_aNaN, aNaN, false, 0);163 TEST_SPECIAL(neg_aNaN, aNaN, aNaN, false, 0);164 TEST_SPECIAL(neg_aNaN, neg_aNaN, aNaN, false, 0);165 TEST_SPECIAL(aNaN, sNaN, aNaN, false, FE_INVALID);166 TEST_SPECIAL(aNaN, neg_sNaN, aNaN, false, FE_INVALID);167 TEST_SPECIAL(neg_aNaN, sNaN, aNaN, false, FE_INVALID);168 TEST_SPECIAL(neg_aNaN, neg_sNaN, aNaN, false, FE_INVALID);169 TEST_SPECIAL(sNaN, aNaN, aNaN, false, FE_INVALID);170 TEST_SPECIAL(sNaN, neg_aNaN, aNaN, false, FE_INVALID);171 TEST_SPECIAL(neg_sNaN, aNaN, aNaN, false, FE_INVALID);172 TEST_SPECIAL(neg_sNaN, neg_aNaN, aNaN, false, FE_INVALID);173 TEST_SPECIAL(sNaN, sNaN, aNaN, false, FE_INVALID);174 TEST_SPECIAL(sNaN, neg_sNaN, aNaN, false, FE_INVALID);175 TEST_SPECIAL(neg_sNaN, sNaN, aNaN, false, FE_INVALID);176 TEST_SPECIAL(neg_sNaN, neg_sNaN, aNaN, false, FE_INVALID);177 178 TEST_SPECIAL(val_6_5, val_2_25, two, false, 0);179 TEST_SPECIAL(val_neg_6_5, val_2_25, neg_two, false, 0);180 TEST_SPECIAL(val_6_5, val_neg_2_25, two, false, 0);181 TEST_SPECIAL(val_neg_6_5, val_neg_2_25, neg_two, false, 0);182 183 TEST_SPECIAL(max_normal, max_normal, zero, false, 0);184 TEST_SPECIAL(max_normal, -max_normal, zero, false, 0);185 TEST_SPECIAL(max_normal, min_normal, zero, false, 0);186 TEST_SPECIAL(max_normal, -min_normal, zero, false, 0);187 TEST_SPECIAL(max_normal, min_denormal, zero, false, 0);188 TEST_SPECIAL(max_normal, -min_denormal, zero, false, 0);189 TEST_SPECIAL(-max_normal, max_normal, neg_zero, false, 0);190 TEST_SPECIAL(-max_normal, -max_normal, neg_zero, false, 0);191 TEST_SPECIAL(-max_normal, min_normal, neg_zero, false, 0);192 TEST_SPECIAL(-max_normal, -min_normal, neg_zero, false, 0);193 TEST_SPECIAL(-max_normal, min_denormal, neg_zero, false, 0);194 TEST_SPECIAL(-max_normal, -min_denormal, neg_zero, false, 0);195 196 TEST_SPECIAL(min_normal, max_normal, min_normal, false, 0);197 TEST_SPECIAL(min_normal, -max_normal, min_normal, false, 0);198 TEST_SPECIAL(min_normal, min_normal, zero, false, 0);199 TEST_SPECIAL(min_normal, -min_normal, zero, false, 0);200 TEST_SPECIAL(min_normal, min_denormal, zero, false, 0);201 TEST_SPECIAL(min_normal, -min_denormal, zero, false, 0);202 TEST_SPECIAL(-min_normal, max_normal, -min_normal, false, 0);203 TEST_SPECIAL(-min_normal, -max_normal, -min_normal, false, 0);204 TEST_SPECIAL(-min_normal, min_normal, neg_zero, false, 0);205 TEST_SPECIAL(-min_normal, -min_normal, neg_zero, false, 0);206 TEST_SPECIAL(-min_normal, min_denormal, neg_zero, false, 0);207 TEST_SPECIAL(-min_normal, -min_denormal, neg_zero, false, 0);208 209 TEST_SPECIAL(min_denormal, max_normal, min_denormal, false, 0);210 TEST_SPECIAL(min_denormal, -max_normal, min_denormal, false, 0);211 TEST_SPECIAL(min_denormal, min_normal, min_denormal, false, 0);212 TEST_SPECIAL(min_denormal, -min_normal, min_denormal, false, 0);213 TEST_SPECIAL(min_denormal, min_denormal, zero, false, 0);214 TEST_SPECIAL(min_denormal, -min_denormal, zero, false, 0);215 TEST_SPECIAL(-min_denormal, max_normal, -min_denormal, false, 0);216 TEST_SPECIAL(-min_denormal, -max_normal, -min_denormal, false, 0);217 TEST_SPECIAL(-min_denormal, min_normal, -min_denormal, false, 0);218 TEST_SPECIAL(-min_denormal, -min_normal, -min_denormal, false, 0);219 TEST_SPECIAL(-min_denormal, min_denormal, neg_zero, false, 0);220 TEST_SPECIAL(-min_denormal, -min_denormal, neg_zero, false, 0);221 }222 223 void testRegularExtreme(FModFunc f) {224 if constexpr (sizeof(T) < sizeof(float))225 return;226 TEST_REGULAR(T(0x1p127), T(0x3p-149), T(0x1p-149));227 TEST_REGULAR(T(0x1p127), T(-0x3p-149), T(0x1p-149));228 TEST_REGULAR(T(0x1p127), T(0x3p-148), T(0x1p-147));229 TEST_REGULAR(T(0x1p127), T(-0x3p-148), T(0x1p-147));230 TEST_REGULAR(T(0x1p127), T(0x3p-126), T(0x1p-125));231 TEST_REGULAR(T(0x1p127), T(-0x3p-126), T(0x1p-125));232 TEST_REGULAR(T(-0x1p127), T(0x3p-149), T(-0x1p-149));233 TEST_REGULAR(T(-0x1p127), T(-0x3p-149), T(-0x1p-149));234 TEST_REGULAR(T(-0x1p127), T(0x3p-148), T(-0x1p-147));235 TEST_REGULAR(T(-0x1p127), T(-0x3p-148), T(-0x1p-147));236 TEST_REGULAR(T(-0x1p127), T(0x3p-126), T(-0x1p-125));237 TEST_REGULAR(T(-0x1p127), T(-0x3p-126), T(-0x1p-125));238 239 if constexpr (sizeof(T) < sizeof(double))240 return;241 TEST_REGULAR(T(0x1p1023), T(0x3p-1074), T(0x1p-1073));242 TEST_REGULAR(T(0x1p1023), T(-0x3p-1074), T(0x1p-1073));243 TEST_REGULAR(T(0x1p1023), T(0x3p-1073), T(0x1p-1073));244 TEST_REGULAR(T(0x1p1023), T(-0x3p-1073), T(0x1p-1073));245 TEST_REGULAR(T(0x1p1023), T(0x3p-1022), T(0x1p-1021));246 TEST_REGULAR(T(0x1p1023), T(-0x3p-1022), T(0x1p-1021));247 TEST_REGULAR(T(-0x1p1023), T(0x3p-1074), T(-0x1p-1073));248 TEST_REGULAR(T(-0x1p1023), T(-0x3p-1074), T(-0x1p-1073));249 TEST_REGULAR(T(-0x1p1023), T(0x3p-1073), T(-0x1p-1073));250 TEST_REGULAR(T(-0x1p1023), T(-0x3p-1073), T(-0x1p-1073));251 TEST_REGULAR(T(-0x1p1023), T(0x3p-1022), T(-0x1p-1021));252 TEST_REGULAR(T(-0x1p1023), T(-0x3p-1022), T(-0x1p-1021));253 }254};255 256#define LIST_FMOD_TESTS(T, func) \257 using LlvmLibcFmodTest = FmodTest<T>; \258 TEST_F(LlvmLibcFmodTest, SpecialNumbers) { testSpecialNumbers(&func); } \259 TEST_F(LlvmLibcFmodTest, RegularExtreme) { testRegularExtreme(&func); }260 261#endif // LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H262