Skip to content

Commit da30197

Browse files
sribee8Sriya Pratipati
andauthored
[libc] Fuzz tests for fsqrt, f16sqrt, and hypot (#150489)
Added fuzz tests for f16sqrt, fsqrt, and hypot --------- Co-authored-by: Sriya Pratipati <[email protected]>
1 parent 2571924 commit da30197

File tree

4 files changed

+200
-0
lines changed

4 files changed

+200
-0
lines changed

libc/fuzzing/math/CMakeLists.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,30 @@ add_libc_fuzzer(
205205
DEPENDS
206206
libc.src.math.cbrt
207207
)
208+
209+
add_libc_fuzzer(
210+
fsqrt_fuzz
211+
NEED_MPFR
212+
SRCS
213+
fsqrt_fuzz.cpp
214+
DEPENDS
215+
libc.src.math.fsqrt
216+
)
217+
218+
add_libc_fuzzer(
219+
f16sqrt_fuzz
220+
NEED_MPFR
221+
SRCS
222+
f16sqrt_fuzz.cpp
223+
DEPENDS
224+
libc.src.math.f16sqrt
225+
)
226+
227+
add_libc_fuzzer(
228+
hypot_fuzz
229+
NEED_MPFR
230+
SRCS
231+
hypot_fuzz.cpp
232+
DEPENDS
233+
libc.src.math.hypot
234+
)

libc/fuzzing/math/f16sqrt_fuzz.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//===-- f16sqrt_fuzz.cpp --------------------------------------------------===//
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+
/// Fuzzing test for llvm-libc f16sqrt implementation.
10+
///
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "src/math/f16sqrt.h"
14+
#include "utils/MPFRWrapper/mpfr_inc.h"
15+
#include <cstdint>
16+
#include <cstring>
17+
#include <iostream>
18+
#include <math.h>
19+
20+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
21+
mpfr_t input;
22+
mpfr_t out;
23+
mpfr_init2(input, 53);
24+
mpfr_init2(out, 128);
25+
for (size_t i = 0; i < size / sizeof(double); ++i) {
26+
double x;
27+
std::memcpy(&x, data, sizeof(double));
28+
data += sizeof(double);
29+
30+
// remove NaN, inf, and values outside the accepted range
31+
if (isnan(x) || isinf(x) || x < 0)
32+
continue;
33+
// signed zeros already tested in unit tests
34+
if (signbit(x) && x == 0.0)
35+
continue;
36+
37+
mpfr_set_d(input, x, MPFR_RNDN);
38+
mpfr_sqrt(out, input, MPFR_RNDN);
39+
float16 to_compare = mpfr_get_d(out, MPFR_RNDN);
40+
41+
float16 result = LIBC_NAMESPACE::f16sqrt(x);
42+
43+
if (result != to_compare) {
44+
std::cout << std::hexfloat << "Failing input: " << x << std::endl;
45+
std::cout << std::hexfloat
46+
<< "Failing output: " << static_cast<float>(result)
47+
<< std::endl;
48+
std::cout << std::hexfloat
49+
<< "Expected: " << static_cast<float>(to_compare) << std::endl;
50+
__builtin_trap();
51+
}
52+
}
53+
mpfr_clear(input);
54+
mpfr_clear(out);
55+
return 0;
56+
}

libc/fuzzing/math/fsqrt_fuzz.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//===-- fsqrt_fuzz.cpp ----------------------------------------------------===//
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+
/// Fuzzing test for llvm-libc fsqrt implementation.
10+
///
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "src/math/fsqrt.h"
14+
#include "utils/MPFRWrapper/mpfr_inc.h"
15+
#include <cstdint>
16+
#include <cstring>
17+
#include <iostream>
18+
#include <math.h>
19+
20+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
21+
mpfr_t input;
22+
mpfr_t out;
23+
mpfr_init2(input, 53);
24+
mpfr_init2(out, 128);
25+
for (size_t i = 0; i < size / sizeof(double); ++i) {
26+
double x;
27+
std::memcpy(&x, data, sizeof(double));
28+
data += sizeof(double);
29+
30+
// remove NaN, inf, and values outside the accepted range
31+
if (isnan(x) || isinf(x) || x < 0)
32+
continue;
33+
// signed zeros already tested in unit tests
34+
if (signbit(x) && x == 0.0)
35+
continue;
36+
37+
mpfr_set_d(input, x, MPFR_RNDN);
38+
mpfr_sqrt(out, input, MPFR_RNDN);
39+
float to_compare = mpfr_get_flt(out, MPFR_RNDN);
40+
41+
float result = LIBC_NAMESPACE::fsqrt(x);
42+
43+
if (result != to_compare) {
44+
std::cout << std::hexfloat << "Failing input: " << x << std::endl;
45+
std::cout << std::hexfloat << "Failing output: " << result << std::endl;
46+
std::cout << std::hexfloat << "Expected: " << to_compare << std::endl;
47+
__builtin_trap();
48+
}
49+
}
50+
mpfr_clear(input);
51+
mpfr_clear(out);
52+
return 0;
53+
}

libc/fuzzing/math/hypot_fuzz.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//===-- hypot_fuzz.cpp ----------------------------------------------------===//
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+
/// Fuzzing test for llvm-libc hypot implementation.
10+
///
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "src/math/hypot.h"
14+
#include "utils/MPFRWrapper/mpfr_inc.h"
15+
#include <cstdint>
16+
#include <cstring>
17+
#include <iostream>
18+
#include <math.h>
19+
20+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
21+
mpfr_t in_x;
22+
mpfr_t in_y;
23+
mpfr_t out;
24+
mpfr_init2(in_x, 53);
25+
mpfr_init2(in_y, 53);
26+
mpfr_init2(out, 128);
27+
28+
for (size_t i = 0; i < size / (2 * sizeof(double)); ++i) {
29+
double x;
30+
double y;
31+
32+
std::memcpy(&x, data, sizeof(double));
33+
data += sizeof(double);
34+
std::memcpy(&y, data, sizeof(double));
35+
data += sizeof(double);
36+
37+
// remove NaN, inf, and signed zeros
38+
if (isnan(x) || isinf(x) || (signbit(x) && x == 0.0))
39+
return 0;
40+
if (isnan(y) || isinf(y) || (signbit(y) && y == 0.0))
41+
return 0;
42+
43+
mpfr_set_d(in_x, x, MPFR_RNDN);
44+
mpfr_set_d(in_y, y, MPFR_RNDN);
45+
46+
int output = mpfr_hypot(out, in_x, in_y, MPFR_RNDN);
47+
mpfr_subnormalize(out, output, MPFR_RNDN);
48+
double to_compare = mpfr_get_d(out, MPFR_RNDN);
49+
50+
double result = LIBC_NAMESPACE::hypot(x, y);
51+
52+
if (result != to_compare) {
53+
std::cout << std::hexfloat << "Failing x: " << x << std::endl;
54+
std::cout << std::hexfloat << "Failing y: " << y << std::endl;
55+
std::cout << std::hexfloat << "Failing output: " << result << std::endl;
56+
std::cout << std::hexfloat << "Expected: " << to_compare << std::endl;
57+
__builtin_trap();
58+
}
59+
}
60+
mpfr_clear(in_x);
61+
mpfr_clear(in_y);
62+
mpfr_clear(out);
63+
return 0;
64+
}

0 commit comments

Comments
 (0)