68 lines · cpp
1// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.2// See https://llvm.org/LICENSE.txt for license information.3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception4 5// Do not attempt to use LLVM ostream etc from gtest.6// #define GTEST_NO_LLVM_SUPPORT 17 8#include "../nsan.h"9#include "gtest/gtest.h"10 11#include <cmath>12 13namespace __nsan {14 15template <typename FT, auto next> void TestFT() {16 // Basic local tests anchored at 0.0.17 ASSERT_EQ(GetULPDiff<FT>(0.0, 0.0), 0);18 ASSERT_EQ(GetULPDiff<FT>(-0.0, 0.0), 0);19 ASSERT_EQ(GetULPDiff<FT>(next(-0.0, -1.0), 0.0), 1);20 ASSERT_EQ(GetULPDiff<FT>(next(0.0, 1.0), -0.0), 1);21 ASSERT_EQ(GetULPDiff<FT>(next(-0.0, -1.0), next(0.0, 1.0)), 2);22 // Basic local tests anchored at 2.0.23 ASSERT_EQ(GetULPDiff<FT>(next(2.0, 1.0), 2.0), 1);24 ASSERT_EQ(GetULPDiff<FT>(next(2.0, 3.0), 2.0), 1);25 ASSERT_EQ(GetULPDiff<FT>(next(2.0, 1.0), next(2.0, 3.0)), 2);26 27 ASSERT_NE(GetULPDiff<FT>(-0.01, 0.01), kMaxULPDiff);28 29 // Basic local tests anchored at a random number.30 const FT X = 4863.5123;31 const FT To = 2 * X;32 FT Y = X;33 ASSERT_EQ(GetULPDiff<FT>(X, Y), 0);34 ASSERT_EQ(GetULPDiff<FT>(-X, -Y), 0);35 Y = next(Y, To);36 ASSERT_EQ(GetULPDiff<FT>(X, Y), 1);37 ASSERT_EQ(GetULPDiff<FT>(-X, -Y), 1);38 Y = next(Y, To);39 ASSERT_EQ(GetULPDiff<FT>(X, Y), 2);40 ASSERT_EQ(GetULPDiff<FT>(-X, -Y), 2);41 Y = next(Y, To);42 ASSERT_EQ(GetULPDiff<FT>(X, Y), 3);43 ASSERT_EQ(GetULPDiff<FT>(-X, -Y), 3);44 45 // Values with larger differences.46 static constexpr const __sanitizer::u64 MantissaSize =47 __sanitizer::u64{1} << FTInfo<FT>::kMantissaBits;48 ASSERT_EQ(GetULPDiff<FT>(1.0, next(2.0, 1.0)), MantissaSize - 1);49 ASSERT_EQ(GetULPDiff<FT>(1.0, 2.0), MantissaSize);50 ASSERT_EQ(GetULPDiff<FT>(1.0, next(2.0, 3.0)), MantissaSize + 1);51 ASSERT_EQ(GetULPDiff<FT>(1.0, 3.0), (3 * MantissaSize) / 2);52}53 54TEST(NSanTest, Float) { TestFT<float, nextafterf>(); }55 56TEST(NSanTest, Double) {57 TestFT<double, static_cast<double (*)(double, double)>(nextafter)>();58}59 60TEST(NSanTest, Float128) {61 // Very basic tests. FIXME: improve when we have nextafter<__float128>.62 ASSERT_EQ(GetULPDiff<__float128>(0.0, 0.0), 0);63 ASSERT_EQ(GetULPDiff<__float128>(-0.0, 0.0), 0);64 ASSERT_NE(GetULPDiff<__float128>(-0.01, 0.01), kMaxULPDiff);65}66 67} // end namespace __nsan68