diff --git a/libc/fuzzing/math/CMakeLists.txt b/libc/fuzzing/math/CMakeLists.txt --- a/libc/fuzzing/math/CMakeLists.txt +++ b/libc/fuzzing/math/CMakeLists.txt @@ -1,65 +1,50 @@ add_libc_fuzzer( - ldexp_differential_fuzz + math_differential_fuzz SRCS - ldexp_differential_fuzz.cpp + math_differential_fuzz.cpp HDRS - LdExpDiff.h + Compare.h + RemQuoDiff.h + SingleInputSingleOutputDiff.h + TwoInputSingleOutputDiff.h DEPENDS + libc.src.math.ceil + libc.src.math.ceilf + libc.src.math.ceill + libc.src.math.fdim + libc.src.math.fdimf + libc.src.math.fdiml + libc.src.math.floor + libc.src.math.floorf + libc.src.math.floorl + libc.src.math.frexp + libc.src.math.frexpf + libc.src.math.frexpl + libc.src.math.hypotf libc.src.math.ldexp - libc.utils.FPUtil.fputil -) - -add_libc_fuzzer( - ldexpf_differential_fuzz - SRCS - ldexpf_differential_fuzz.cpp - HDRS - LdExpDiff.h - DEPENDS libc.src.math.ldexpf - libc.utils.FPUtil.fputil -) - -add_libc_fuzzer( - ldexpl_differential_fuzz - SRCS - ldexpl_differential_fuzz.cpp - HDRS - LdExpDiff.h - DEPENDS libc.src.math.ldexpl - libc.utils.FPUtil.fputil -) - -add_libc_fuzzer( - remquo_differential_fuzz - SRCS - remquo_differential_fuzz.cpp - HDRS - RemQuoDiff.h - DEPENDS + libc.src.math.logb + libc.src.math.logbf + libc.src.math.logbl + libc.src.math.modf + libc.src.math.modff + libc.src.math.modfl + libc.src.math.sqrt + libc.src.math.sqrtf + libc.src.math.sqrtl + libc.src.math.remainder + libc.src.math.remainderf + libc.src.math.remainderl libc.src.math.remquo - libc.utils.FPUtil.fputil -) - -add_libc_fuzzer( - remquof_differential_fuzz - SRCS - remquof_differential_fuzz.cpp - HDRS - RemQuoDiff.h - DEPENDS libc.src.math.remquof - libc.utils.FPUtil.fputil -) - -add_libc_fuzzer( - remquol_differential_fuzz - SRCS - remquol_differential_fuzz.cpp - HDRS - RemQuoDiff.h - DEPENDS libc.src.math.remquol + libc.src.math.round + libc.src.math.roundf + libc.src.math.roundl + libc.src.math.trunc + libc.src.math.truncf + libc.src.math.truncl libc.utils.FPUtil.fputil + libc.utils.CPP.standalone_cpp ) diff --git a/libc/fuzzing/math/Compare.h b/libc/fuzzing/math/Compare.h new file mode 100644 --- /dev/null +++ b/libc/fuzzing/math/Compare.h @@ -0,0 +1,34 @@ +//===-- Template functions to compare scalar values -------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_FUZZING_MATH_COMPARE_H +#define LLVM_LIBC_FUZZING_MATH_COMPARE_H + +#include "utils/CPP/TypeTraits.h" + +template +__llvm_libc::cpp::EnableIfType<__llvm_libc::cpp::IsFloatingPointType::Value, + bool> +ValuesEqual(T x1, T x2) { + __llvm_libc::fputil::FPBits bits1(x1); + __llvm_libc::fputil::FPBits bits2(x2); + // If either is NaN, we want both to be NaN. + if (bits1.isNaN() || bits2.isNaN()) + return bits2.isNaN() && bits2.isNaN(); + + // For all other values, we want the values to be bitwise equal. + return bits1.bitsAsUInt() == bits2.bitsAsUInt(); +} + +template +__llvm_libc::cpp::EnableIfType<__llvm_libc::cpp::IsIntegral::Value, bool> +ValuesEqual(T x1, T x2) { + return x1 == x1; +} + +#endif // LLVM_LIBC_FUZZING_MATH_COMPARE_H diff --git a/libc/fuzzing/math/LdExpDiff.h b/libc/fuzzing/math/LdExpDiff.h deleted file mode 100644 --- a/libc/fuzzing/math/LdExpDiff.h +++ /dev/null @@ -1,44 +0,0 @@ -//===-- Template for diffing ldexp results ----------------------*- C++ -*-===// -// -// 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 "utils/FPUtil/FPBits.h" - -#include -#include -#include - -template using LdExpFunc = T (*)(T, int); - -template -void LdExpDiff(LdExpFunc func1, LdExpFunc func2, const uint8_t *data, - size_t size) { - constexpr size_t typeSize = sizeof(T); - if (size < typeSize + sizeof(int)) - return; - - T x = *reinterpret_cast(data); - T i = *reinterpret_cast(data + typeSize); - - T result1 = func1(x, i); - T result2 = func2(x, i); - if (isnan(result1)) { - if (!isnan(result2)) - __builtin_trap(); - return; - } - if (isinf(result1)) { - if (isinf(result2) != isinf(result1)) - __builtin_trap(); - return; - } - - __llvm_libc::fputil::FPBits bits1(result1); - __llvm_libc::fputil::FPBits bits2(result2); - if (bits1.bitsAsUInt() != bits2.bitsAsUInt()) - __builtin_trap(); -} diff --git a/libc/fuzzing/math/RemQuoDiff.h b/libc/fuzzing/math/RemQuoDiff.h --- a/libc/fuzzing/math/RemQuoDiff.h +++ b/libc/fuzzing/math/RemQuoDiff.h @@ -33,11 +33,9 @@ __builtin_trap(); return; } - if (isinf(remainder1)) { - if (isinf(remainder2) != isinf(remainder1)) - __builtin_trap(); - return; - } + + if (isinf(remainder2) != isinf(remainder1)) + __builtin_trap(); // Compare only the 3 LS bits of the quotient. if ((q1 & 0x7) != (q2 & 0x7)) diff --git a/libc/fuzzing/math/SingleInputSingleOutputDiff.h b/libc/fuzzing/math/SingleInputSingleOutputDiff.h new file mode 100644 --- /dev/null +++ b/libc/fuzzing/math/SingleInputSingleOutputDiff.h @@ -0,0 +1,61 @@ +//===-- Template to diff single-input-single-output functions ---*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_FUZZING_MATH_SINGLE_INPUT_SINGLE_OUTPUT_DIFF_H +#define LLVM_LIBC_FUZZING_MATH_SINGLE_INPUT_SINGLE_OUTPUT_DIFF_H + +#include "fuzzing/math/Compare.h" +#include "utils/FPUtil/FPBits.h" + +#include +#include +#include + +template using SingleInputSingleOutputFunc = T (*)(T); + +template +void SingleInputSingleOutputDiff(SingleInputSingleOutputFunc func1, + SingleInputSingleOutputFunc func2, + const uint8_t *data, size_t size) { + if (size < sizeof(T)) + return; + + T x = *reinterpret_cast(data); + + T result1 = func1(x); + T result2 = func2(x); + + if (!ValuesEqual(result1, result2)) + __builtin_trap(); +} + +template +using SingleInputSingleOutputWithSideEffectFunc = T1 (*)(T1, T2 *); + +template +void SingleInputSingleOutputWithSideEffectDiff( + SingleInputSingleOutputWithSideEffectFunc func1, + SingleInputSingleOutputWithSideEffectFunc func2, + const uint8_t *data, size_t size) { + if (size < sizeof(T1)) + return; + + T1 x = *reinterpret_cast(data); + T2 sideEffect1, sideEffect2; + + T1 result1 = func1(x, &sideEffect1); + T1 result2 = func2(x, &sideEffect2); + + if (!ValuesEqual(result1, result2)) + __builtin_trap(); + + if (!ValuesEqual(sideEffect1, sideEffect2)) + __builtin_trap(); +} + +#endif // LLVM_LIBC_FUZZING_MATH_SINGLE_INPUT_SINGLE_OUTPUT_DIFF_H diff --git a/libc/fuzzing/math/TwoInputSingleOutputDiff.h b/libc/fuzzing/math/TwoInputSingleOutputDiff.h new file mode 100644 --- /dev/null +++ b/libc/fuzzing/math/TwoInputSingleOutputDiff.h @@ -0,0 +1,40 @@ +//===-- Template to diff two-input-single-output functions ------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_FUZZING_MATH_TWO_INPUT_SINGLE_OUTPUT_DIFF_H +#define LLVM_LIBC_FUZZING_MATH_TWO_INPUT_SINGLE_OUTPUT_DIFF_H + +#include "fuzzing/math/Compare.h" +#include "utils/FPUtil/FPBits.h" + +#include +#include +#include + +template +using TwoInputSingleOutputFunc = T1 (*)(T1, T2); + +template +void TwoInputSingleOutputDiff(TwoInputSingleOutputFunc func1, + TwoInputSingleOutputFunc func2, + const uint8_t *data, size_t size) { + constexpr size_t t1Size = sizeof(T1); + if (size < t1Size + sizeof(T2)) + return; + + T1 x = *reinterpret_cast(data); + T2 y = *reinterpret_cast(data + t1Size); + + T1 result1 = func1(x, y); + T1 result2 = func2(x, y); + + if (!ValuesEqual(result1, result2)) + __builtin_trap(); +} + +#endif // LLVM_LIBC_FUZZING_MATH_TWO_INPUT_SINGLE_OUTPUT_DIFF_H diff --git a/libc/fuzzing/math/ldexp_differential_fuzz.cpp b/libc/fuzzing/math/ldexp_differential_fuzz.cpp deleted file mode 100644 --- a/libc/fuzzing/math/ldexp_differential_fuzz.cpp +++ /dev/null @@ -1,23 +0,0 @@ -//===-- ldexp_differential_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 -// -//===----------------------------------------------------------------------===// -/// -/// Differential fuzz test for llvm-libc ldexp implementation. -/// -//===----------------------------------------------------------------------===// - -#include "fuzzing/math/LdExpDiff.h" -#include "src/math/ldexp.h" - -#include -#include -#include - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - LdExpDiff(&__llvm_libc::ldexp, &::ldexp, data, size); - return 0; -} diff --git a/libc/fuzzing/math/ldexpf_differential_fuzz.cpp b/libc/fuzzing/math/ldexpf_differential_fuzz.cpp deleted file mode 100644 --- a/libc/fuzzing/math/ldexpf_differential_fuzz.cpp +++ /dev/null @@ -1,23 +0,0 @@ -//===-- ldexpf_differential_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 -// -//===----------------------------------------------------------------------===// -/// -/// Differential fuzz test for llvm-libc ldexpf implementation. -/// -//===----------------------------------------------------------------------===// - -#include "fuzzing/math/LdExpDiff.h" -#include "src/math/ldexpf.h" - -#include -#include -#include - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - LdExpDiff(&__llvm_libc::ldexpf, &::ldexpf, data, size); - return 0; -} diff --git a/libc/fuzzing/math/ldexpl_differential_fuzz.cpp b/libc/fuzzing/math/ldexpl_differential_fuzz.cpp deleted file mode 100644 --- a/libc/fuzzing/math/ldexpl_differential_fuzz.cpp +++ /dev/null @@ -1,23 +0,0 @@ -//===-- ldexpl_differential_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 -// -//===----------------------------------------------------------------------===// -/// -/// Differential fuzz test for llvm-libc ldexpl implementation. -/// -//===----------------------------------------------------------------------===// - -#include "fuzzing/math/LdExpDiff.h" -#include "src/math/ldexpl.h" - -#include -#include -#include - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - LdExpDiff(&__llvm_libc::ldexpl, &::ldexpl, data, size); - return 0; -} diff --git a/libc/fuzzing/math/math_differential_fuzz.cpp b/libc/fuzzing/math/math_differential_fuzz.cpp new file mode 100644 --- /dev/null +++ b/libc/fuzzing/math/math_differential_fuzz.cpp @@ -0,0 +1,152 @@ +//===-- ldexp_differential_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 +// +//===----------------------------------------------------------------------===// +/// +/// Differential fuzz test for llvm-libc ldexp implementation. +/// +//===----------------------------------------------------------------------===// + +#include "fuzzing/math/RemQuoDiff.h" +#include "fuzzing/math/SingleInputSingleOutputDiff.h" +#include "fuzzing/math/TwoInputSingleOutputDiff.h" + +#include "src/math/ceil.h" +#include "src/math/ceilf.h" +#include "src/math/ceill.h" + +#include "src/math/fdim.h" +#include "src/math/fdimf.h" +#include "src/math/fdiml.h" + +#include "src/math/floor.h" +#include "src/math/floorf.h" +#include "src/math/floorl.h" + +#include "src/math/frexp.h" +#include "src/math/frexpf.h" +#include "src/math/frexpl.h" + +#include "src/math/hypotf.h" + +#include "src/math/ldexp.h" +#include "src/math/ldexpf.h" +#include "src/math/ldexpl.h" + +#include "src/math/logb.h" +#include "src/math/logbf.h" +#include "src/math/logbl.h" + +#include "src/math/modf.h" +#include "src/math/modff.h" +#include "src/math/modfl.h" + +#include "src/math/remainder.h" +#include "src/math/remainderf.h" +#include "src/math/remainderl.h" + +#include "src/math/remquo.h" +#include "src/math/remquof.h" +#include "src/math/remquol.h" + +#include "src/math/round.h" +#include "src/math/roundf.h" +#include "src/math/roundl.h" + +#include "src/math/sqrt.h" +#include "src/math/sqrtf.h" +#include "src/math/sqrtl.h" + +#include "src/math/trunc.h" +#include "src/math/truncf.h" +#include "src/math/truncl.h" + +#include +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + + SingleInputSingleOutputDiff(&__llvm_libc::ceilf, &::ceilf, data, size); + SingleInputSingleOutputDiff(&__llvm_libc::ceil, &::ceil, data, size); + SingleInputSingleOutputDiff(&__llvm_libc::ceill, &::ceill, data, + size); + + SingleInputSingleOutputDiff(&__llvm_libc::floorf, &::floorf, data, + size); + SingleInputSingleOutputDiff(&__llvm_libc::floor, &::floor, data, + size); + SingleInputSingleOutputDiff(&__llvm_libc::floorl, &::floorl, + data, size); + + SingleInputSingleOutputDiff(&__llvm_libc::roundf, &::roundf, data, + size); + SingleInputSingleOutputDiff(&__llvm_libc::round, &::round, data, + size); + SingleInputSingleOutputDiff(&__llvm_libc::roundl, &::roundl, + data, size); + + SingleInputSingleOutputDiff(&__llvm_libc::truncf, &::truncf, data, + size); + SingleInputSingleOutputDiff(&__llvm_libc::trunc, &::trunc, data, + size); + SingleInputSingleOutputDiff(&__llvm_libc::truncl, &::truncl, + data, size); + + SingleInputSingleOutputDiff(&__llvm_libc::logbf, &::logbf, data, size); + SingleInputSingleOutputDiff(&__llvm_libc::logb, &::logb, data, size); + SingleInputSingleOutputDiff(&__llvm_libc::logbl, &::logbl, data, + size); + + TwoInputSingleOutputDiff(&__llvm_libc::hypotf, &::hypotf, data, + size); + + TwoInputSingleOutputDiff(&__llvm_libc::remainderf, + &::remainderf, data, size); + TwoInputSingleOutputDiff(&__llvm_libc::remainder, + &::remainder, data, size); + TwoInputSingleOutputDiff(&__llvm_libc::remainderl, + &::remainderl, data, size); + + TwoInputSingleOutputDiff(&__llvm_libc::fdimf, &::fdimf, data, + size); + TwoInputSingleOutputDiff(&__llvm_libc::fdim, &::fdim, data, + size); + TwoInputSingleOutputDiff(&__llvm_libc::fdiml, + &::fdiml, data, size); + + SingleInputSingleOutputDiff(&__llvm_libc::sqrtf, &::sqrtf, data, size); + SingleInputSingleOutputDiff(&__llvm_libc::sqrt, &::sqrt, data, size); + SingleInputSingleOutputDiff(&__llvm_libc::sqrtl, &::sqrtl, data, + size); + + SingleInputSingleOutputWithSideEffectDiff(&__llvm_libc::frexpf, + &::frexpf, data, size); + SingleInputSingleOutputWithSideEffectDiff(&__llvm_libc::frexp, + &::frexp, data, size); + SingleInputSingleOutputWithSideEffectDiff( + &__llvm_libc::frexpl, &::frexpl, data, size); + + SingleInputSingleOutputWithSideEffectDiff(&__llvm_libc::modff, + &::modff, data, size); + SingleInputSingleOutputWithSideEffectDiff( + &__llvm_libc::modf, &::modf, data, size); + SingleInputSingleOutputWithSideEffectDiff( + &__llvm_libc::modfl, &::modfl, data, size); + + TwoInputSingleOutputDiff(&__llvm_libc::ldexpf, &::ldexpf, data, + size); + TwoInputSingleOutputDiff(&__llvm_libc::ldexp, &::ldexp, data, + size); + TwoInputSingleOutputDiff(&__llvm_libc::ldexpl, &::ldexpl, + data, size); + + RemQuoDiff(&__llvm_libc::remquof, &::remquof, data, size); + RemQuoDiff(&__llvm_libc::remquo, &::remquo, data, size); + RemQuoDiff(&__llvm_libc::remquol, &::remquol, data, size); + + return 0; +} diff --git a/libc/fuzzing/math/remquo_differential_fuzz.cpp b/libc/fuzzing/math/remquo_differential_fuzz.cpp deleted file mode 100644 --- a/libc/fuzzing/math/remquo_differential_fuzz.cpp +++ /dev/null @@ -1,23 +0,0 @@ -//===-- remquo_differential_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 -// -//===----------------------------------------------------------------------===// -/// -/// Differential fuzz test for llvm-libc remquo implementation. -/// -//===----------------------------------------------------------------------===// - -#include "fuzzing/math/RemQuoDiff.h" -#include "src/math/remquo.h" - -#include -#include -#include - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - RemQuoDiff(&__llvm_libc::remquo, &::remquo, data, size); - return 0; -} diff --git a/libc/fuzzing/math/remquof_differential_fuzz.cpp b/libc/fuzzing/math/remquof_differential_fuzz.cpp deleted file mode 100644 --- a/libc/fuzzing/math/remquof_differential_fuzz.cpp +++ /dev/null @@ -1,23 +0,0 @@ -//===-- remquof_differential_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 -// -//===----------------------------------------------------------------------===// -/// -/// Differential fuzz test for llvm-libc remquof implementation. -/// -//===----------------------------------------------------------------------===// - -#include "fuzzing/math/RemQuoDiff.h" -#include "src/math/remquof.h" - -#include -#include -#include - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - RemQuoDiff(&__llvm_libc::remquof, &::remquof, data, size); - return 0; -} diff --git a/libc/fuzzing/math/remquol_differential_fuzz.cpp b/libc/fuzzing/math/remquol_differential_fuzz.cpp deleted file mode 100644 --- a/libc/fuzzing/math/remquol_differential_fuzz.cpp +++ /dev/null @@ -1,23 +0,0 @@ -//===-- remquol_differential_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 -// -//===----------------------------------------------------------------------===// -/// -/// Differential fuzz test for llvm-libc remquol implementation. -/// -//===----------------------------------------------------------------------===// - -#include "fuzzing/math/RemQuoDiff.h" -#include "src/math/remquol.h" - -#include -#include -#include - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - RemQuoDiff(&__llvm_libc::remquol, &::remquol, data, size); - return 0; -}