From 129f09fe72e83cfc371c8586979b31c885e7c229 Mon Sep 17 00:00:00 2001 From: Sriya Pratipati Date: Thu, 10 Jul 2025 17:12:06 +0000 Subject: [PATCH 1/6] [libc] sqrt and log functions fuzz tests added fuzz tests for sqrt and log functions --- libc/fuzzing/math/CMakeLists.txt | 45 +++++++++++++++++++++++++++++++ libc/fuzzing/math/log10_fuzz.cpp | 38 ++++++++++++++++++++++++++ libc/fuzzing/math/log1p_fuzz.cpp | 38 ++++++++++++++++++++++++++ libc/fuzzing/math/log2_fuzz.cpp | 38 ++++++++++++++++++++++++++ libc/fuzzing/math/log_fuzz.cpp | 38 ++++++++++++++++++++++++++ libc/fuzzing/math/sincos_fuzz.cpp | 2 +- libc/fuzzing/math/sqrt_fuzz.cpp | 38 ++++++++++++++++++++++++++ 7 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 libc/fuzzing/math/log10_fuzz.cpp create mode 100644 libc/fuzzing/math/log1p_fuzz.cpp create mode 100644 libc/fuzzing/math/log2_fuzz.cpp create mode 100644 libc/fuzzing/math/log_fuzz.cpp create mode 100644 libc/fuzzing/math/sqrt_fuzz.cpp diff --git a/libc/fuzzing/math/CMakeLists.txt b/libc/fuzzing/math/CMakeLists.txt index e3c29651917fc..06f8f024762b9 100644 --- a/libc/fuzzing/math/CMakeLists.txt +++ b/libc/fuzzing/math/CMakeLists.txt @@ -124,3 +124,48 @@ add_libc_fuzzer( DEPENDS libc.src.math.sincos ) + +add_libc_fuzzer( + log_fuzz + NEED_MPFR + SRCS + log_fuzz.cpp + DEPENDS + libc.src.math.log +) + +add_libc_fuzzer( + log10_fuzz + NEED_MPFR + SRCS + log10_fuzz.cpp + DEPENDS + libc.src.math.log10 +) + +add_libc_fuzzer( + log1p_fuzz + NEED_MPFR + SRCS + log1p_fuzz.cpp + DEPENDS + libc.src.math.log1p +) + +add_libc_fuzzer( + log2_fuzz + NEED_MPFR + SRCS + log2_fuzz.cpp + DEPENDS + libc.src.math.log2 +) + +add_libc_fuzzer( + sqrt_fuzz + NEED_MPFR + SRCS + sqrt_fuzz.cpp + DEPENDS + libc.src.math.sqrt +) diff --git a/libc/fuzzing/math/log10_fuzz.cpp b/libc/fuzzing/math/log10_fuzz.cpp new file mode 100644 index 0000000000000..b5233588e83f8 --- /dev/null +++ b/libc/fuzzing/math/log10_fuzz.cpp @@ -0,0 +1,38 @@ +//===-- log10_fuzz.cpp ----------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// Fuzzing test for llvm-libc log10 implementation. +/// +//===----------------------------------------------------------------------===// + +#include "src/math/log10.h" +#include "utils/MPFRWrapper/mpfr_inc.h" +#include + +extern "C" int LLVMFuzzerTestOneInput(double x) { + // remove NaN and inf and values outside accepted range + if (isnan(x) || isinf(x) || x < 0) + return 0; + // signed zeros already tested in unit tests + if (signbit(x) && x == 0.0) + return 0; + mpfr_t input; + mpfr_init2(input, 53); + mpfr_set_d(input, x, MPFR_RNDN); + int output = mpfr_log10(input, input, MPFR_RNDN); + mpfr_subnormalize(input, output, MPFR_RNDN); + double to_compare = mpfr_get_d(input, MPFR_RNDN); + + double result = LIBC_NAMESPACE::log10(x); + + if (result != to_compare) + __builtin_trap(); + + mpfr_clear(input); + return 0; +} diff --git a/libc/fuzzing/math/log1p_fuzz.cpp b/libc/fuzzing/math/log1p_fuzz.cpp new file mode 100644 index 0000000000000..c40aad018794f --- /dev/null +++ b/libc/fuzzing/math/log1p_fuzz.cpp @@ -0,0 +1,38 @@ +//===-- log1p_fuzz.cpp ----------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// Fuzzing test for llvm-libc log1p implementation. +/// +//===----------------------------------------------------------------------===// + +#include "src/math/log1p.h" +#include "utils/MPFRWrapper/mpfr_inc.h" +#include + +extern "C" int LLVMFuzzerTestOneInput(double x) { + // remove NaN and inf and values outside accepted range + if (isnan(x) || isinf(x) || x < 0) + return 0; + // signed zeros already tested in unit tests + if (signbit(x) && x == 0.0) + return 0; + mpfr_t input; + mpfr_init2(input, 53); + mpfr_set_d(input, x, MPFR_RNDN); + int output = mpfr_log1p(input, input, MPFR_RNDN); + mpfr_subnormalize(input, output, MPFR_RNDN); + double to_compare = mpfr_get_d(input, MPFR_RNDN); + + double result = LIBC_NAMESPACE::log1p(x); + + if (result != to_compare) + __builtin_trap(); + + mpfr_clear(input); + return 0; +} diff --git a/libc/fuzzing/math/log2_fuzz.cpp b/libc/fuzzing/math/log2_fuzz.cpp new file mode 100644 index 0000000000000..3a7d9956b4bea --- /dev/null +++ b/libc/fuzzing/math/log2_fuzz.cpp @@ -0,0 +1,38 @@ +//===-- log2_fuzz.cpp -----------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// Fuzzing test for llvm-libc log2 implementation. +/// +//===----------------------------------------------------------------------===// + +#include "src/math/log2.h" +#include "utils/MPFRWrapper/mpfr_inc.h" +#include + +extern "C" int LLVMFuzzerTestOneInput(double x) { + // remove NaN and inf and values outside accepted range + if (isnan(x) || isinf(x) || x < 0) + return 0; + // signed zeros already tested in unit tests + if (signbit(x) && x == 0.0) + return 0; + mpfr_t input; + mpfr_init2(input, 53); + mpfr_set_d(input, x, MPFR_RNDN); + int output = mpfr_log2(input, input, MPFR_RNDN); + mpfr_subnormalize(input, output, MPFR_RNDN); + double to_compare = mpfr_get_d(input, MPFR_RNDN); + + double result = LIBC_NAMESPACE::log2(x); + + if (result != to_compare) + __builtin_trap(); + + mpfr_clear(input); + return 0; +} diff --git a/libc/fuzzing/math/log_fuzz.cpp b/libc/fuzzing/math/log_fuzz.cpp new file mode 100644 index 0000000000000..1271fb73fd1a0 --- /dev/null +++ b/libc/fuzzing/math/log_fuzz.cpp @@ -0,0 +1,38 @@ +//===-- log_fuzz.cpp ------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// Fuzzing test for llvm-libc log implementation. +/// +//===----------------------------------------------------------------------===// + +#include "src/math/log.h" +#include "utils/MPFRWrapper/mpfr_inc.h" +#include + +extern "C" int LLVMFuzzerTestOneInput(double x) { + // remove NaN and inf and values outside accepted range + if (isnan(x) || isinf(x) || x < 0) + return 0; + // signed zeros already tested in unit tests + if (signbit(x) && x == 0.0) + return 0; + mpfr_t input; + mpfr_init2(input, 53); + mpfr_set_d(input, x, MPFR_RNDN); + int output = mpfr_log(input, input, MPFR_RNDN); + mpfr_subnormalize(input, output, MPFR_RNDN); + double to_compare = mpfr_get_d(input, MPFR_RNDN); + + double result = LIBC_NAMESPACE::log(x); + + if (result != to_compare) + __builtin_trap(); + + mpfr_clear(input); + return 0; +} diff --git a/libc/fuzzing/math/sincos_fuzz.cpp b/libc/fuzzing/math/sincos_fuzz.cpp index 8cc6f7291a3df..fd3dfae23168c 100644 --- a/libc/fuzzing/math/sincos_fuzz.cpp +++ b/libc/fuzzing/math/sincos_fuzz.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// /// -/// Fuzzing test for llvm-libc cos implementation. +/// Fuzzing test for llvm-libc sincos implementation. /// //===----------------------------------------------------------------------===// diff --git a/libc/fuzzing/math/sqrt_fuzz.cpp b/libc/fuzzing/math/sqrt_fuzz.cpp new file mode 100644 index 0000000000000..48e17f481a256 --- /dev/null +++ b/libc/fuzzing/math/sqrt_fuzz.cpp @@ -0,0 +1,38 @@ +//===-- sqrt_fuzz.cpp -----------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// Fuzzing test for llvm-libc sqrt implementation. +/// +//===----------------------------------------------------------------------===// + +#include "src/math/sqrt.h" +#include "utils/MPFRWrapper/mpfr_inc.h" +#include + +extern "C" int LLVMFuzzerTestOneInput(double x) { + // remove NaN and inf and values outside accepted range + if (isnan(x) || isinf(x) || x < 0) + return 0; + // signed zeros already tested in unit tests + if (signbit(x) && x == 0.0) + return 0; + mpfr_t input; + mpfr_init2(input, 53); + mpfr_set_d(input, x, MPFR_RNDN); + int output = mpfr_sqrt(input, input, MPFR_RNDN); + mpfr_subnormalize(input, output, MPFR_RNDN); + double to_compare = mpfr_get_d(input, MPFR_RNDN); + + double result = LIBC_NAMESPACE::sqrt(x); + + if (result != to_compare) + __builtin_trap(); + + mpfr_clear(input); + return 0; +} From d05a5baedfee2faf890dbb98451c9113136c7ce3 Mon Sep 17 00:00:00 2001 From: Sriya Pratipati Date: Thu, 10 Jul 2025 21:20:29 +0000 Subject: [PATCH 2/6] changed to test internal sqrt --- libc/fuzzing/math/sqrt_fuzz.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libc/fuzzing/math/sqrt_fuzz.cpp b/libc/fuzzing/math/sqrt_fuzz.cpp index 48e17f481a256..4f5f165a1e0f2 100644 --- a/libc/fuzzing/math/sqrt_fuzz.cpp +++ b/libc/fuzzing/math/sqrt_fuzz.cpp @@ -10,7 +10,7 @@ /// //===----------------------------------------------------------------------===// -#include "src/math/sqrt.h" +#include "src/__support/FPUtil/generic/sqrt.h" #include "utils/MPFRWrapper/mpfr_inc.h" #include @@ -28,7 +28,7 @@ extern "C" int LLVMFuzzerTestOneInput(double x) { mpfr_subnormalize(input, output, MPFR_RNDN); double to_compare = mpfr_get_d(input, MPFR_RNDN); - double result = LIBC_NAMESPACE::sqrt(x); + double result = LIBC_NAMESPACE::fputil::sqrt(x); if (result != to_compare) __builtin_trap(); From 4db3dfe12e94a51effa3fd4697a66a6bc747e07d Mon Sep 17 00:00:00 2001 From: Sriya Pratipati Date: Thu, 10 Jul 2025 21:26:38 +0000 Subject: [PATCH 3/6] updated cmake with correct dependancy --- libc/fuzzing/math/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/fuzzing/math/CMakeLists.txt b/libc/fuzzing/math/CMakeLists.txt index 06f8f024762b9..cbe4a278b6b70 100644 --- a/libc/fuzzing/math/CMakeLists.txt +++ b/libc/fuzzing/math/CMakeLists.txt @@ -167,5 +167,5 @@ add_libc_fuzzer( SRCS sqrt_fuzz.cpp DEPENDS - libc.src.math.sqrt + libc.src.__support.FPUtil.generic.sqrt ) From b83fcf37484679faedc651bd564a0a85d313947e Mon Sep 17 00:00:00 2001 From: Sriya Pratipati Date: Mon, 14 Jul 2025 16:35:45 +0000 Subject: [PATCH 4/6] updated condition --- libc/fuzzing/math/log1p_fuzz.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/fuzzing/math/log1p_fuzz.cpp b/libc/fuzzing/math/log1p_fuzz.cpp index c40aad018794f..108baf5c6160c 100644 --- a/libc/fuzzing/math/log1p_fuzz.cpp +++ b/libc/fuzzing/math/log1p_fuzz.cpp @@ -16,7 +16,7 @@ extern "C" int LLVMFuzzerTestOneInput(double x) { // remove NaN and inf and values outside accepted range - if (isnan(x) || isinf(x) || x < 0) + if (isnan(x) || isinf(x) || x < -1) return 0; // signed zeros already tested in unit tests if (signbit(x) && x == 0.0) From 5b5e4e6be3941904893360cc6844abe137fa3e8f Mon Sep 17 00:00:00 2001 From: Sriya Pratipati Date: Tue, 15 Jul 2025 17:39:14 +0000 Subject: [PATCH 5/6] updated tests to correct format --- libc/fuzzing/math/CMakeLists.txt | 9 ------- libc/fuzzing/math/atan_fuzz.cpp | 38 ------------------------------ libc/fuzzing/math/log10_fuzz.cpp | 39 ++++++++++++++++++++----------- libc/fuzzing/math/log1p_fuzz.cpp | 39 ++++++++++++++++++++----------- libc/fuzzing/math/log2_fuzz.cpp | 39 ++++++++++++++++++++----------- libc/fuzzing/math/log_fuzz.cpp | 40 ++++++++++++++++++++------------ libc/fuzzing/math/sqrt_fuzz.cpp | 39 ++++++++++++++++++++----------- 7 files changed, 125 insertions(+), 118 deletions(-) delete mode 100644 libc/fuzzing/math/atan_fuzz.cpp diff --git a/libc/fuzzing/math/CMakeLists.txt b/libc/fuzzing/math/CMakeLists.txt index cbe4a278b6b70..4425fcd974455 100644 --- a/libc/fuzzing/math/CMakeLists.txt +++ b/libc/fuzzing/math/CMakeLists.txt @@ -98,15 +98,6 @@ add_libc_fuzzer( libc.src.math.cos ) -add_libc_fuzzer( - atan_fuzz - NEED_MPFR - SRCS - atan_fuzz.cpp - DEPENDS - libc.src.math.atan -) - add_libc_fuzzer( tan_fuzz NEED_MPFR diff --git a/libc/fuzzing/math/atan_fuzz.cpp b/libc/fuzzing/math/atan_fuzz.cpp deleted file mode 100644 index 3b485786e3a63..0000000000000 --- a/libc/fuzzing/math/atan_fuzz.cpp +++ /dev/null @@ -1,38 +0,0 @@ -//===-- atan_fuzz.cpp -----------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// -/// -/// Fuzzing test for llvm-libc atan implementation. -/// -//===----------------------------------------------------------------------===// - -#include "src/math/atan.h" -#include "utils/MPFRWrapper/mpfr_inc.h" -#include - -extern "C" int LLVMFuzzerTestOneInput(double x) { - // remove NaN and inf - if (isnan(x) || isinf(x)) - return 0; - // signed zeros already tested in unit tests - if (signbit(x) && x == 0.0) - return 0; - mpfr_t input; - mpfr_init2(input, 53); - mpfr_set_d(input, x, MPFR_RNDN); - int output = mpfr_atan(input, input, MPFR_RNDN); - mpfr_subnormalize(input, output, MPFR_RNDN); - double to_compare = mpfr_get_d(input, MPFR_RNDN); - - double result = LIBC_NAMESPACE::atan(x); - - if (result != to_compare) - __builtin_trap(); - - mpfr_clear(input); - return 0; -} diff --git a/libc/fuzzing/math/log10_fuzz.cpp b/libc/fuzzing/math/log10_fuzz.cpp index b5233588e83f8..3254edc6d4a9b 100644 --- a/libc/fuzzing/math/log10_fuzz.cpp +++ b/libc/fuzzing/math/log10_fuzz.cpp @@ -12,27 +12,38 @@ #include "src/math/log10.h" #include "utils/MPFRWrapper/mpfr_inc.h" +#include +#include +#include #include -extern "C" int LLVMFuzzerTestOneInput(double x) { - // remove NaN and inf and values outside accepted range - if (isnan(x) || isinf(x) || x < 0) - return 0; - // signed zeros already tested in unit tests - if (signbit(x) && x == 0.0) - return 0; +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { mpfr_t input; mpfr_init2(input, 53); - mpfr_set_d(input, x, MPFR_RNDN); - int output = mpfr_log10(input, input, MPFR_RNDN); - mpfr_subnormalize(input, output, MPFR_RNDN); - double to_compare = mpfr_get_d(input, MPFR_RNDN); + for (size_t i = 0; i < size / sizeof(double); ++i) { + double x; + std::memcpy(&x, data, sizeof(double)); + // remove NaN and inf and values outside accepted range + if (isnan(x) || isinf(x) || x < 0) + return 0; + // signed zeros already tested in unit tests + if (signbit(x) && x == 0.0) + return 0; - double result = LIBC_NAMESPACE::log10(x); + mpfr_set_d(input, x, MPFR_RNDN); + int output = mpfr_log10(input, input, MPFR_RNDN); + mpfr_subnormalize(input, output, MPFR_RNDN); + double to_compare = mpfr_get_d(input, MPFR_RNDN); - if (result != to_compare) - __builtin_trap(); + double result = LIBC_NAMESPACE::log10(x); + if (result != to_compare) { + std::cout << std::hexfloat << "Failing input: " << x << std::endl; + std::cout << std::hexfloat << "Failing output: " << result << std::endl; + std::cout << std::hexfloat << "Expected: " << to_compare << std::endl; + __builtin_trap(); + } + } mpfr_clear(input); return 0; } diff --git a/libc/fuzzing/math/log1p_fuzz.cpp b/libc/fuzzing/math/log1p_fuzz.cpp index 108baf5c6160c..70186363b5a41 100644 --- a/libc/fuzzing/math/log1p_fuzz.cpp +++ b/libc/fuzzing/math/log1p_fuzz.cpp @@ -12,27 +12,38 @@ #include "src/math/log1p.h" #include "utils/MPFRWrapper/mpfr_inc.h" +#include +#include +#include #include -extern "C" int LLVMFuzzerTestOneInput(double x) { - // remove NaN and inf and values outside accepted range - if (isnan(x) || isinf(x) || x < -1) - return 0; - // signed zeros already tested in unit tests - if (signbit(x) && x == 0.0) - return 0; +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { mpfr_t input; mpfr_init2(input, 53); - mpfr_set_d(input, x, MPFR_RNDN); - int output = mpfr_log1p(input, input, MPFR_RNDN); - mpfr_subnormalize(input, output, MPFR_RNDN); - double to_compare = mpfr_get_d(input, MPFR_RNDN); + for (size_t i = 0; i < size / sizeof(double); ++i) { + double x; + std::memcpy(&x, data, sizeof(double)); + // remove NaN and inf and values outside accepted range + if (isnan(x) || isinf(x) || x < -1) + return 0; + // signed zeros already tested in unit tests + if (signbit(x) && x == 0.0) + return 0; - double result = LIBC_NAMESPACE::log1p(x); + mpfr_set_d(input, x, MPFR_RNDN); + int output = mpfr_log1p(input, input, MPFR_RNDN); + mpfr_subnormalize(input, output, MPFR_RNDN); + double to_compare = mpfr_get_d(input, MPFR_RNDN); - if (result != to_compare) - __builtin_trap(); + double result = LIBC_NAMESPACE::log1p(x); + if (result != to_compare) { + std::cout << std::hexfloat << "Failing input: " << x << std::endl; + std::cout << std::hexfloat << "Failing output: " << result << std::endl; + std::cout << std::hexfloat << "Expected: " << to_compare << std::endl; + __builtin_trap(); + } + } mpfr_clear(input); return 0; } diff --git a/libc/fuzzing/math/log2_fuzz.cpp b/libc/fuzzing/math/log2_fuzz.cpp index 3a7d9956b4bea..7bf77212c4d47 100644 --- a/libc/fuzzing/math/log2_fuzz.cpp +++ b/libc/fuzzing/math/log2_fuzz.cpp @@ -12,27 +12,38 @@ #include "src/math/log2.h" #include "utils/MPFRWrapper/mpfr_inc.h" +#include +#include +#include #include -extern "C" int LLVMFuzzerTestOneInput(double x) { - // remove NaN and inf and values outside accepted range - if (isnan(x) || isinf(x) || x < 0) - return 0; - // signed zeros already tested in unit tests - if (signbit(x) && x == 0.0) - return 0; +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { mpfr_t input; mpfr_init2(input, 53); - mpfr_set_d(input, x, MPFR_RNDN); - int output = mpfr_log2(input, input, MPFR_RNDN); - mpfr_subnormalize(input, output, MPFR_RNDN); - double to_compare = mpfr_get_d(input, MPFR_RNDN); + for (size_t i = 0; i < size / sizeof(double); ++i) { + double x; + std::memcpy(&x, data, sizeof(double)); + // remove NaN and inf and values outside accepted range + if (isnan(x) || isinf(x) || x < 0) + return 0; + // signed zeros already tested in unit tests + if (signbit(x) && x == 0.0) + return 0; - double result = LIBC_NAMESPACE::log2(x); + mpfr_set_d(input, x, MPFR_RNDN); + int output = mpfr_log2(input, input, MPFR_RNDN); + mpfr_subnormalize(input, output, MPFR_RNDN); + double to_compare = mpfr_get_d(input, MPFR_RNDN); - if (result != to_compare) - __builtin_trap(); + double result = LIBC_NAMESPACE::log2(x); + if (result != to_compare) { + std::cout << std::hexfloat << "Failing input: " << x << std::endl; + std::cout << std::hexfloat << "Failing output: " << result << std::endl; + std::cout << std::hexfloat << "Expected: " << to_compare << std::endl; + __builtin_trap(); + } + } mpfr_clear(input); return 0; } diff --git a/libc/fuzzing/math/log_fuzz.cpp b/libc/fuzzing/math/log_fuzz.cpp index 1271fb73fd1a0..4b84b2b72dd78 100644 --- a/libc/fuzzing/math/log_fuzz.cpp +++ b/libc/fuzzing/math/log_fuzz.cpp @@ -12,27 +12,37 @@ #include "src/math/log.h" #include "utils/MPFRWrapper/mpfr_inc.h" +#include +#include +#include #include -extern "C" int LLVMFuzzerTestOneInput(double x) { - // remove NaN and inf and values outside accepted range - if (isnan(x) || isinf(x) || x < 0) - return 0; - // signed zeros already tested in unit tests - if (signbit(x) && x == 0.0) - return 0; +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { mpfr_t input; mpfr_init2(input, 53); - mpfr_set_d(input, x, MPFR_RNDN); - int output = mpfr_log(input, input, MPFR_RNDN); - mpfr_subnormalize(input, output, MPFR_RNDN); - double to_compare = mpfr_get_d(input, MPFR_RNDN); + for (size_t i = 0; i < size / sizeof(double); ++i) { + double x; + std::memcpy(&x, data, sizeof(double)); + // remove NaN and inf and values outside accepted range + if (isnan(x) || isinf(x) || x < 0) + return 0; + // signed zeros already tested in unit tests + if (signbit(x) && x == 0.0) + return 0; + mpfr_set_d(input, x, MPFR_RNDN); + int output = mpfr_log(input, input, MPFR_RNDN); + mpfr_subnormalize(input, output, MPFR_RNDN); + double to_compare = mpfr_get_d(input, MPFR_RNDN); - double result = LIBC_NAMESPACE::log(x); - - if (result != to_compare) - __builtin_trap(); + double result = LIBC_NAMESPACE::log(x); + if (result != to_compare) { + std::cout << std::hexfloat << "Failing input: " << x << std::endl; + std::cout << std::hexfloat << "Failing output: " << result << std::endl; + std::cout << std::hexfloat << "Expected: " << to_compare << std::endl; + __builtin_trap(); + } + } mpfr_clear(input); return 0; } diff --git a/libc/fuzzing/math/sqrt_fuzz.cpp b/libc/fuzzing/math/sqrt_fuzz.cpp index 4f5f165a1e0f2..447517a55d247 100644 --- a/libc/fuzzing/math/sqrt_fuzz.cpp +++ b/libc/fuzzing/math/sqrt_fuzz.cpp @@ -12,27 +12,38 @@ #include "src/__support/FPUtil/generic/sqrt.h" #include "utils/MPFRWrapper/mpfr_inc.h" +#include +#include +#include #include -extern "C" int LLVMFuzzerTestOneInput(double x) { - // remove NaN and inf and values outside accepted range - if (isnan(x) || isinf(x) || x < 0) - return 0; - // signed zeros already tested in unit tests - if (signbit(x) && x == 0.0) - return 0; +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { mpfr_t input; mpfr_init2(input, 53); - mpfr_set_d(input, x, MPFR_RNDN); - int output = mpfr_sqrt(input, input, MPFR_RNDN); - mpfr_subnormalize(input, output, MPFR_RNDN); - double to_compare = mpfr_get_d(input, MPFR_RNDN); + for (size_t i = 0; i < size / sizeof(double); ++i) { + double x; + std::memcpy(&x, data, sizeof(double)); + // remove NaN and inf and values outside accepted range + if (isnan(x) || isinf(x) || x < 0) + return 0; + // signed zeros already tested in unit tests + if (signbit(x) && x == 0.0) + return 0; - double result = LIBC_NAMESPACE::fputil::sqrt(x); + mpfr_set_d(input, x, MPFR_RNDN); + int output = mpfr_sqrt(input, input, MPFR_RNDN); + mpfr_subnormalize(input, output, MPFR_RNDN); + double to_compare = mpfr_get_d(input, MPFR_RNDN); - if (result != to_compare) - __builtin_trap(); + double result = LIBC_NAMESPACE::fputil::sqrt(x); + if (result != to_compare) { + std::cout << std::hexfloat << "Failing input: " << x << std::endl; + std::cout << std::hexfloat << "Failing output: " << result << std::endl; + std::cout << std::hexfloat << "Expected: " << to_compare << std::endl; + __builtin_trap(); + } + } mpfr_clear(input); return 0; } From c42124d9a674ea1dd19107ba1ff7a88213ed6189 Mon Sep 17 00:00:00 2001 From: Sriya Pratipati Date: Tue, 15 Jul 2025 18:14:55 +0000 Subject: [PATCH 6/6] added incrementing the data pointer --- libc/fuzzing/math/log10_fuzz.cpp | 2 ++ libc/fuzzing/math/log1p_fuzz.cpp | 1 + libc/fuzzing/math/log2_fuzz.cpp | 2 ++ libc/fuzzing/math/log_fuzz.cpp | 2 ++ libc/fuzzing/math/sqrt_fuzz.cpp | 1 + 5 files changed, 8 insertions(+) diff --git a/libc/fuzzing/math/log10_fuzz.cpp b/libc/fuzzing/math/log10_fuzz.cpp index 3254edc6d4a9b..23134f4903a45 100644 --- a/libc/fuzzing/math/log10_fuzz.cpp +++ b/libc/fuzzing/math/log10_fuzz.cpp @@ -23,6 +23,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { for (size_t i = 0; i < size / sizeof(double); ++i) { double x; std::memcpy(&x, data, sizeof(double)); + data += sizeof(double); + // remove NaN and inf and values outside accepted range if (isnan(x) || isinf(x) || x < 0) return 0; diff --git a/libc/fuzzing/math/log1p_fuzz.cpp b/libc/fuzzing/math/log1p_fuzz.cpp index 70186363b5a41..5e138a65e3716 100644 --- a/libc/fuzzing/math/log1p_fuzz.cpp +++ b/libc/fuzzing/math/log1p_fuzz.cpp @@ -23,6 +23,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { for (size_t i = 0; i < size / sizeof(double); ++i) { double x; std::memcpy(&x, data, sizeof(double)); + data += sizeof(double); // remove NaN and inf and values outside accepted range if (isnan(x) || isinf(x) || x < -1) return 0; diff --git a/libc/fuzzing/math/log2_fuzz.cpp b/libc/fuzzing/math/log2_fuzz.cpp index 7bf77212c4d47..aa19649b95126 100644 --- a/libc/fuzzing/math/log2_fuzz.cpp +++ b/libc/fuzzing/math/log2_fuzz.cpp @@ -23,6 +23,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { for (size_t i = 0; i < size / sizeof(double); ++i) { double x; std::memcpy(&x, data, sizeof(double)); + data += sizeof(double); + // remove NaN and inf and values outside accepted range if (isnan(x) || isinf(x) || x < 0) return 0; diff --git a/libc/fuzzing/math/log_fuzz.cpp b/libc/fuzzing/math/log_fuzz.cpp index 4b84b2b72dd78..03aa678d1f16c 100644 --- a/libc/fuzzing/math/log_fuzz.cpp +++ b/libc/fuzzing/math/log_fuzz.cpp @@ -23,6 +23,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { for (size_t i = 0; i < size / sizeof(double); ++i) { double x; std::memcpy(&x, data, sizeof(double)); + data += sizeof(double); + // remove NaN and inf and values outside accepted range if (isnan(x) || isinf(x) || x < 0) return 0; diff --git a/libc/fuzzing/math/sqrt_fuzz.cpp b/libc/fuzzing/math/sqrt_fuzz.cpp index 447517a55d247..e81cf1afd3728 100644 --- a/libc/fuzzing/math/sqrt_fuzz.cpp +++ b/libc/fuzzing/math/sqrt_fuzz.cpp @@ -23,6 +23,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { for (size_t i = 0; i < size / sizeof(double); ++i) { double x; std::memcpy(&x, data, sizeof(double)); + data += sizeof(double); // remove NaN and inf and values outside accepted range if (isnan(x) || isinf(x) || x < 0) return 0;