1 //===-- Unittests for sincosf ---------------------------------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/math/sincosf.h" 10 #include "test/src/math/sdcomp26094.h" 11 #include "utils/CPP/Array.h" 12 #include "utils/FPUtil/BitPatterns.h" 13 #include "utils/FPUtil/ClassificationFunctions.h" 14 #include "utils/FPUtil/FloatOperations.h" 15 #include "utils/FPUtil/FloatProperties.h" 16 #include "utils/MPFRWrapper/MPFRUtils.h" 17 #include "utils/UnitTest/Test.h" 18 #include <math.h> 19 20 #include <errno.h> 21 #include <stdint.h> 22 23 using __llvm_libc::fputil::isNegativeQuietNaN; 24 using __llvm_libc::fputil::isQuietNaN; 25 using __llvm_libc::fputil::valueAsBits; 26 using __llvm_libc::fputil::valueFromBits; 27 28 using BitPatterns = __llvm_libc::fputil::BitPatterns<float>; 29 30 using __llvm_libc::testing::sdcomp26094Values; 31 32 namespace mpfr = __llvm_libc::testing::mpfr; 33 34 TEST(LlvmLibcSinCosfTest, SpecialNumbers) { 35 errno = 0; 36 float sin, cos; 37 38 __llvm_libc::sincosf(valueFromBits(BitPatterns::aQuietNaN), &sin, &cos); 39 EXPECT_TRUE(isQuietNaN(cos)); 40 EXPECT_TRUE(isQuietNaN(sin)); 41 EXPECT_EQ(errno, 0); 42 43 __llvm_libc::sincosf(valueFromBits(BitPatterns::aNegativeQuietNaN), &sin, 44 &cos); 45 EXPECT_TRUE(isNegativeQuietNaN(cos)); 46 EXPECT_TRUE(isNegativeQuietNaN(sin)); 47 EXPECT_EQ(errno, 0); 48 49 __llvm_libc::sincosf(valueFromBits(BitPatterns::aSignallingNaN), &sin, &cos); 50 EXPECT_TRUE(isQuietNaN(cos)); 51 EXPECT_TRUE(isQuietNaN(sin)); 52 EXPECT_EQ(errno, 0); 53 54 __llvm_libc::sincosf(valueFromBits(BitPatterns::aNegativeSignallingNaN), &sin, 55 &cos); 56 EXPECT_TRUE(isNegativeQuietNaN(cos)); 57 EXPECT_TRUE(isNegativeQuietNaN(sin)); 58 EXPECT_EQ(errno, 0); 59 60 __llvm_libc::sincosf(valueFromBits(BitPatterns::zero), &sin, &cos); 61 EXPECT_EQ(BitPatterns::one, valueAsBits(cos)); 62 EXPECT_EQ(BitPatterns::zero, valueAsBits(sin)); 63 EXPECT_EQ(errno, 0); 64 65 __llvm_libc::sincosf(valueFromBits(BitPatterns::negZero), &sin, &cos); 66 EXPECT_EQ(BitPatterns::one, valueAsBits(cos)); 67 EXPECT_EQ(BitPatterns::negZero, valueAsBits(sin)); 68 EXPECT_EQ(errno, 0); 69 70 errno = 0; 71 __llvm_libc::sincosf(valueFromBits(BitPatterns::inf), &sin, &cos); 72 EXPECT_TRUE(isQuietNaN(cos)); 73 EXPECT_TRUE(isQuietNaN(sin)); 74 EXPECT_EQ(errno, EDOM); 75 76 errno = 0; 77 __llvm_libc::sincosf(valueFromBits(BitPatterns::negInf), &sin, &cos); 78 EXPECT_TRUE(isQuietNaN(cos)); 79 EXPECT_TRUE(isQuietNaN(sin)); 80 EXPECT_EQ(errno, EDOM); 81 } 82 83 TEST(LlvmLibcSinCosfTest, InFloatRange) { 84 constexpr uint32_t count = 1000000; 85 constexpr uint32_t step = UINT32_MAX / count; 86 for (uint32_t i = 0, v = 0; i <= count; ++i, v += step) { 87 float x = valueFromBits(v); 88 if (isnan(x) || isinf(x)) 89 continue; 90 91 float sin, cos; 92 __llvm_libc::sincosf(x, &sin, &cos); 93 ASSERT_MPFR_MATCH(mpfr::Operation::Cos, x, cos, 1.0); 94 ASSERT_MPFR_MATCH(mpfr::Operation::Sin, x, sin, 1.0); 95 } 96 } 97 98 // For small values, cos(x) is 1 and sin(x) is x. 99 TEST(LlvmLibcSinCosfTest, SmallValues) { 100 uint32_t bits = 0x17800000; 101 float x = valueFromBits(bits); 102 float result_cos, result_sin; 103 __llvm_libc::sincosf(x, &result_sin, &result_cos); 104 EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, result_cos, 1.0); 105 EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, result_sin, 1.0); 106 EXPECT_EQ(BitPatterns::one, valueAsBits(result_cos)); 107 EXPECT_EQ(bits, valueAsBits(result_sin)); 108 109 bits = 0x00400000; 110 x = valueFromBits(bits); 111 __llvm_libc::sincosf(x, &result_sin, &result_cos); 112 EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, result_cos, 1.0); 113 EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, result_sin, 1.0); 114 EXPECT_EQ(BitPatterns::one, valueAsBits(result_cos)); 115 EXPECT_EQ(bits, valueAsBits(result_sin)); 116 } 117 118 // SDCOMP-26094: check sinf in the cases for which the range reducer 119 // returns values furthest beyond its nominal upper bound of pi/4. 120 TEST(LlvmLibcSinCosfTest, SDCOMP_26094) { 121 for (uint32_t v : sdcomp26094Values) { 122 float x = valueFromBits(v); 123 float sin, cos; 124 __llvm_libc::sincosf(x, &sin, &cos); 125 EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, cos, 1.0); 126 EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, sin, 1.0); 127 } 128 } 129