diff --git a/libc/test/src/math/differential_testing/BinaryOpSingleOutputDiff.h b/libc/test/src/math/differential_testing/BinaryOpSingleOutputDiff.h --- a/libc/test/src/math/differential_testing/BinaryOpSingleOutputDiff.h +++ b/libc/test/src/math/differential_testing/BinaryOpSingleOutputDiff.h @@ -22,6 +22,40 @@ public: typedef T Func(T, T); + static uint64_t run_diff_in_range(Func myFunc, Func otherFunc, + UIntType startingBit, UIntType endingBit, + UIntType N, + testutils::OutputFileStream &log) { + uint64_t result = 0; + if (endingBit < startingBit) { + return result; + } + + UIntType step = (endingBit - startingBit) / N; + for (UIntType bitsX = startingBit, bitsY = endingBit;; + bitsX += step, bitsY -= step) { + T x = T(FPBits(bitsX)); + T y = T(FPBits(bitsY)); + FPBits myBits = FPBits(myFunc(x, y)); + FPBits otherBits = FPBits(otherFunc(x, y)); + if (myBits.uintval() != otherBits.uintval()) { + result++; + log << " Input: " << bitsX << ", " << bitsY << " (" << x << ", " + << y << ")\n" + << " My result: " << myBits.uintval() << " (" << myBits.get_val() + << ")\n" + << "Other result: " << otherBits.uintval() << " (" + << otherBits.get_val() << ")\n" + << '\n'; + } + + if (endingBit - bitsX < step) { + break; + } + } + return result; + } + static void run_perf_in_range(Func myFunc, Func otherFunc, UIntType startingBit, UIntType endingBit, UIntType N, testutils::OutputFileStream &log) { @@ -84,6 +118,26 @@ myFunc, otherFunc, /* startingBit= */ FPBits(T(0x1.0p-10)).uintval(), /* endingBit= */ FPBits(T(0x1.0p+10)).uintval(), 10'000'001, log); } + + static void run_diff(Func myFunc, Func otherFunc, const char *logFile) { + uint64_t diffCount = 0; + testutils::OutputFileStream log(logFile); + log << " Diff tests with inputs in denormal range:\n"; + diffCount += run_diff_in_range( + myFunc, otherFunc, /* startingBit= */ UIntType(0), + /* endingBit= */ FPBits::MAX_SUBNORMAL, 1'000'001, log); + log << "\n Diff tests with inputs in normal range:\n"; + diffCount += run_diff_in_range( + myFunc, otherFunc, /* startingBit= */ FPBits::MIN_NORMAL, + /* endingBit= */ FPBits::MAX_NORMAL, 100'000'001, log); + log << "\n Diff tests with inputs in normal range with exponents " + "close to each other:\n"; + diffCount += run_diff_in_range( + myFunc, otherFunc, /* startingBit= */ FPBits(T(0x1.0p-10)).uintval(), + /* endingBit= */ FPBits(T(0x1.0p+10)).uintval(), 10'000'001, log); + + log << "Total number of differing results: " << diffCount << '\n'; + } }; } // namespace testing diff --git a/libc/test/src/math/differential_testing/CMakeLists.txt b/libc/test/src/math/differential_testing/CMakeLists.txt --- a/libc/test/src/math/differential_testing/CMakeLists.txt +++ b/libc/test/src/math/differential_testing/CMakeLists.txt @@ -427,6 +427,17 @@ -fno-builtin ) +add_diff_binary( + hypotf_diff + SRCS + hypotf_diff.cpp + DEPENDS + .binary_op_single_output_diff + libc.src.math.hypotf + COMPILE_OPTIONS + -fno-builtin +) + add_diff_binary( hypotf_perf SRCS @@ -438,6 +449,17 @@ -fno-builtin ) +add_diff_binary( + hypot_diff + SRCS + hypot_diff.cpp + DEPENDS + .binary_op_single_output_diff + libc.src.math.hypot + COMPILE_OPTIONS + -fno-builtin +) + add_diff_binary( hypot_perf SRCS diff --git a/libc/test/src/math/differential_testing/hypot_diff.cpp b/libc/test/src/math/differential_testing/hypot_diff.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/math/differential_testing/hypot_diff.cpp @@ -0,0 +1,16 @@ +//===-- Differential test for hypot ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "BinaryOpSingleOutputDiff.h" + +#include "src/math/hypot.h" + +#include + +BINARY_OP_SINGLE_OUTPUT_DIFF(double, __llvm_libc::hypot, ::hypot, + "hypot_diff.log") diff --git a/libc/test/src/math/differential_testing/hypotf_diff.cpp b/libc/test/src/math/differential_testing/hypotf_diff.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/math/differential_testing/hypotf_diff.cpp @@ -0,0 +1,16 @@ +//===-- Differential test for hypotf --------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "BinaryOpSingleOutputDiff.h" + +#include "src/math/hypotf.h" + +#include + +BINARY_OP_SINGLE_OUTPUT_DIFF(float, __llvm_libc::hypotf, ::hypotf, + "hypotf_diff.log")