summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-05-07 23:06:18 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-05-07 23:06:18 +0000
commitc2bad861842aba1bb2058d583bfa74e94cfa1ffd (patch)
tree0836890776e077e1c2fb5b24d7a031bba6544f75
parent8348f296eda4ff996db7db63fa0e79263763a99e (diff)
parent5c76e7b22aaa87ac1d8f0ae7e100327ff29eb427 (diff)
downloadllvm-libc-sdk-release.tar.gz
Snap for 11812660 from 5c76e7b22aaa87ac1d8f0ae7e100327ff29eb427 to sdk-releasesdk-releasebusytown-mac-infra-release
Change-Id: I3a00b36fa823ba65e8dc241910f6b555e0451511
-rw-r--r--include/llvm-libc-macros/linux/fcntl-macros.h31
-rw-r--r--include/llvm-libc-types/char16_t.h17
-rw-r--r--include/llvm-libc-types/char32_t.h17
-rw-r--r--include/llvm-libc-types/char8_t.h17
-rw-r--r--include/llvm-libc-types/struct_f_owner_ex.h25
-rw-r--r--include/llvm-libc-types/struct_flock.h25
-rw-r--r--include/llvm-libc-types/struct_flock64.h25
-rw-r--r--libc/hdr/fcntl_macros.h22
-rw-r--r--libc/hdr/types/struct_f_owner_ex.h21
-rw-r--r--libc/hdr/types/struct_flock.h21
-rw-r--r--libc/hdr/types/struct_flock64.h21
-rw-r--r--src/__support/fixed_point/sqrt.h16
-rw-r--r--src/fcntl/fcntl.h18
-rw-r--r--src/fcntl/linux/fcntl.cpp93
-rw-r--r--src/math/generic/nearbyintf128.cpp19
-rw-r--r--src/math/generic/scalbnf128.cpp27
-rw-r--r--src/math/nearbyintf128.h20
-rw-r--r--src/math/scalbnf128.h20
-rw-r--r--test/UnitTest/FPMatcher.h21
-rw-r--r--test/src/fcntl/fcntl_test.cpp155
-rw-r--r--test/src/math/scalbnf128_test.cpp13
-rw-r--r--test/src/math/smoke/NearbyIntTest.h100
-rw-r--r--test/src/math/smoke/nearbyint_test.cpp13
-rw-r--r--test/src/math/smoke/nearbyintf128_test.cpp13
-rw-r--r--test/src/math/smoke/nearbyintf_test.cpp13
-rw-r--r--test/src/math/smoke/nearbyintl_test.cpp13
-rw-r--r--test/src/math/smoke/scalbnf128_test.cpp13
-rw-r--r--test/src/stdfix/ISqrtTest.h24
-rw-r--r--test/src/stdfix/SqrtTest.h2
-rw-r--r--test/src/stdfix/uksqrtui_test.cpp9
30 files changed, 830 insertions, 14 deletions
diff --git a/include/llvm-libc-macros/linux/fcntl-macros.h b/include/llvm-libc-macros/linux/fcntl-macros.h
index 1d4e5bbbdc77..8ee95863728e 100644
--- a/include/llvm-libc-macros/linux/fcntl-macros.h
+++ b/include/llvm-libc-macros/linux/fcntl-macros.h
@@ -67,5 +67,36 @@
#define F_SETFD 2
#define F_GETFL 3
#define F_SETFL 4
+#define F_GETLK 5
+#define F_SETLK 6
+#define F_SETLKW 7
+#define F_SETOWN 8
+#define F_GETOWN 9
+#define F_SETSIG 10
+#define F_GETSIG 11
+#define F_GETLK64 12
+#define F_SETLK64 13
+#define F_SETLKW64 14
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+
+// Open File Description Locks.
+#define F_OFD_GETLK 36
+#define F_OFD_SETLK 37
+#define F_OFD_SETLKW 38
+
+// Close on succesful
+#define F_CLOEXEC 1
+
+#define F_RDLCK 0
+#define F_WRLCK 1
+#define F_UNLCK 2
+
+// For Large File Support
+#if defined(_LARGEFILE64_SOURCE)
+#define F_GETLK F_GETLK64
+#define F_SETLK F_SETLK64
+#define F_SETLKW F_SETLKW64
+#endif
#endif // LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H
diff --git a/include/llvm-libc-types/char16_t.h b/include/llvm-libc-types/char16_t.h
new file mode 100644
index 000000000000..1f5847ae771b
--- /dev/null
+++ b/include/llvm-libc-types/char16_t.h
@@ -0,0 +1,17 @@
+//===-- Definition of char16_t type ---------------------------------------===//
+//
+// 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_TYPES_CHAR16_T_H
+#define LLVM_LIBC_TYPES_CHAR16_T_H
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+#include "../llvm-libc-macros/stdint-macros.h"
+typedef uint_least16_t char16_t;
+#endif
+
+#endif // LLVM_LIBC_TYPES_CHAR16_T_H
diff --git a/include/llvm-libc-types/char32_t.h b/include/llvm-libc-types/char32_t.h
new file mode 100644
index 000000000000..20b72dc5d67e
--- /dev/null
+++ b/include/llvm-libc-types/char32_t.h
@@ -0,0 +1,17 @@
+//===-- Definition of char32_t type ---------------------------------------===//
+//
+// 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_TYPES_CHAR32_T_H
+#define LLVM_LIBC_TYPES_CHAR32_T_H
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+#include "../llvm-libc-macros/stdint-macros.h"
+typedef uint_least32_t char32_t;
+#endif
+
+#endif // LLVM_LIBC_TYPES_CHAR32_T_H
diff --git a/include/llvm-libc-types/char8_t.h b/include/llvm-libc-types/char8_t.h
new file mode 100644
index 000000000000..ddadab1afa21
--- /dev/null
+++ b/include/llvm-libc-types/char8_t.h
@@ -0,0 +1,17 @@
+//===-- Definition of char8_t type ----------------------------------------===//
+//
+// 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_TYPES_CHAR8_T_H
+#define LLVM_LIBC_TYPES_CHAR8_T_H
+
+#if !defined(__cplusplus) && defined(__STDC_VERSION__) && \
+ __STDC_VERSION__ >= 202311L
+typedef unsigned char char8_t;
+#endif
+
+#endif // LLVM_LIBC_TYPES_CHAR8_T_H
diff --git a/include/llvm-libc-types/struct_f_owner_ex.h b/include/llvm-libc-types/struct_f_owner_ex.h
new file mode 100644
index 000000000000..c9cc85f69d2b
--- /dev/null
+++ b/include/llvm-libc-types/struct_f_owner_ex.h
@@ -0,0 +1,25 @@
+//===-- Definition of type struct f_owner_ex ------------------------------===//
+//
+// 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_TYPES_STRUCT_F_OWNER_EX_H
+#define LLVM_LIBC_TYPES_STRUCT_F_OWNER_EX_H
+
+#include "llvm-libc-types/pid_t.h"
+
+enum pid_type {
+ F_OWNER_TID = 0,
+ F_OWNER_PID,
+ F_OWNER_PGRP,
+};
+
+struct f_owner_ex {
+ enum pid_type type;
+ pid_t pid;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_F_OWNER_EX_H
diff --git a/include/llvm-libc-types/struct_flock.h b/include/llvm-libc-types/struct_flock.h
new file mode 100644
index 000000000000..51c9d27640ea
--- /dev/null
+++ b/include/llvm-libc-types/struct_flock.h
@@ -0,0 +1,25 @@
+//===-- Definition of type struct flock64 ---------------------------------===//
+//
+// 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_TYPES_STRUCT_FLOCK_H
+#define LLVM_LIBC_TYPES_STRUCT_FLOCK_H
+
+#include "llvm-libc-types/off_t.h"
+#include "llvm-libc-types/pid_t.h"
+
+#include <stdint.h>
+
+struct flock {
+ int16_t l_type;
+ int16_t l_whence;
+ off_t l_start;
+ off_t l_len;
+ pid_t l_pid;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_FLOCK_H
diff --git a/include/llvm-libc-types/struct_flock64.h b/include/llvm-libc-types/struct_flock64.h
new file mode 100644
index 000000000000..ac50003ca62f
--- /dev/null
+++ b/include/llvm-libc-types/struct_flock64.h
@@ -0,0 +1,25 @@
+//===-- Definition of type struct flock64 ---------------------------------===//
+//
+// 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_TYPES_STRUCT_FLOCK64_H
+#define LLVM_LIBC_TYPES_STRUCT_FLOCK64_H
+
+#include "llvm-libc-types/off64_t.h"
+#include "llvm-libc-types/pid_t.h"
+
+#include <stdint.h>
+
+struct flock64 {
+ int16_t l_type;
+ int16_t l_whence;
+ off64_t l_start;
+ off64_t l_len;
+ pid_t l_pid;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_FLOCK64_H
diff --git a/libc/hdr/fcntl_macros.h b/libc/hdr/fcntl_macros.h
new file mode 100644
index 000000000000..828cb984c0cb
--- /dev/null
+++ b/libc/hdr/fcntl_macros.h
@@ -0,0 +1,22 @@
+//===-- Definition of macros from fcntl/fcntl.h ---------------------------===//
+//
+// 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_HDR_FCNTL_MACROS_H
+#define LLVM_LIBC_HDR_FCNTL_MACROS_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-macros/fcntl-macros.h"
+
+#else // Overlay mode
+
+#include <fcntl.h>
+
+#endif // LLVM_LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_FCNTL_MACROS_H
diff --git a/libc/hdr/types/struct_f_owner_ex.h b/libc/hdr/types/struct_f_owner_ex.h
new file mode 100644
index 000000000000..49985115ae4b
--- /dev/null
+++ b/libc/hdr/types/struct_f_owner_ex.h
@@ -0,0 +1,21 @@
+//===-- Proxy for struct f_owner_ex --------------------------------------===//
+//
+// 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_HDR_TYPES_STRUCT_F_OWNER_EX_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_F_OWNER_EX_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_f_owner_ex.h"
+
+#else
+
+#include <fcntl.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_F_OWNER_EX_H
diff --git a/libc/hdr/types/struct_flock.h b/libc/hdr/types/struct_flock.h
new file mode 100644
index 000000000000..a552b91c432b
--- /dev/null
+++ b/libc/hdr/types/struct_flock.h
@@ -0,0 +1,21 @@
+//===-- Proxy for struct flock -------------------------------------------===//
+//
+// 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_HDR_TYPES_STRUCT_FLOCK_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_FLOCK_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_flock.h"
+
+#else
+
+#include <fcntl.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_FLOCK_H
diff --git a/libc/hdr/types/struct_flock64.h b/libc/hdr/types/struct_flock64.h
new file mode 100644
index 000000000000..84fe67816c33
--- /dev/null
+++ b/libc/hdr/types/struct_flock64.h
@@ -0,0 +1,21 @@
+//===-- Proxy for struct flock64 -----------------------------------------===//
+//
+// 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_HDR_TYPES_STRUCT_FLOCK64_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_FLOCK64_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_flock64.h"
+
+#else
+
+#include <fcntl.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_FLOCK64_H
diff --git a/src/__support/fixed_point/sqrt.h b/src/__support/fixed_point/sqrt.h
index 4ec016ceab00..982e318e2d1e 100644
--- a/src/__support/fixed_point/sqrt.h
+++ b/src/__support/fixed_point/sqrt.h
@@ -55,18 +55,22 @@ template <> struct SqrtConfig<unsigned fract> {
// Linear approximation for the initial values, with errors bounded by:
// max(1.5 * 2^-11, eps)
// Generated with Sollya:
- // > for i from 4 to 15 do {
+ // > for i from 4 to 14 do {
// P = fpminimax(sqrt(x), 1, [|16, 16|], [i * 2^-4, (i + 1)*2^-4],
// fixed, absolute);
// print("{", coeff(P, 1), "ur,", coeff(P, 0), "ur},");
// };
+ // For the last interval [15/16, 1), we choose the linear function Q such that
+ // Q(1) = 1 and Q(15/16) = P(15/16),
+ // where P is the polynomial generated by Sollya above for [14/16, 15/16].
+ // This is to prevent overflow in the last interval [15/16, 1).
static constexpr Type FIRST_APPROX[12][2] = {
{0x1.e378p-1ur, 0x1.0ebp-2ur}, {0x1.b512p-1ur, 0x1.2b94p-2ur},
{0x1.91fp-1ur, 0x1.45dcp-2ur}, {0x1.7622p-1ur, 0x1.5e24p-2ur},
{0x1.5f5ap-1ur, 0x1.74e4p-2ur}, {0x1.4c58p-1ur, 0x1.8a4p-2ur},
{0x1.3c1ep-1ur, 0x1.9e84p-2ur}, {0x1.2e0cp-1ur, 0x1.b1d8p-2ur},
{0x1.21aap-1ur, 0x1.c468p-2ur}, {0x1.16bap-1ur, 0x1.d62cp-2ur},
- {0x1.0cfp-1ur, 0x1.e74cp-2ur}, {0x1.0418p-1ur, 0x1.f7ep-2ur},
+ {0x1.0cfp-1ur, 0x1.e74cp-2ur}, {0x1.039p-1ur, 0x1.f8ep-2ur},
};
};
@@ -77,11 +81,15 @@ template <> struct SqrtConfig<unsigned long fract> {
// Linear approximation for the initial values, with errors bounded by:
// max(1.5 * 2^-11, eps)
// Generated with Sollya:
- // > for i from 4 to 15 do {
+ // > for i from 4 to 14 do {
// P = fpminimax(sqrt(x), 1, [|32, 32|], [i * 2^-4, (i + 1)*2^-4],
// fixed, absolute);
// print("{", coeff(P, 1), "ulr,", coeff(P, 0), "ulr},");
// };
+ // For the last interval [15/16, 1), we choose the linear function Q such that
+ // Q(1) = 1 and Q(15/16) = P(15/16),
+ // where P is the polynomial generated by Sollya above for [14/16, 15/16].
+ // This is to prevent overflow in the last interval [15/16, 1).
static constexpr Type FIRST_APPROX[12][2] = {
{0x1.e3779b98p-1ulr, 0x1.0eaff788p-2ulr},
{0x1.b5167872p-1ulr, 0x1.2b908ad4p-2ulr},
@@ -94,7 +102,7 @@ template <> struct SqrtConfig<unsigned long fract> {
{0x1.21b05c0ap-1ulr, 0x1.c45e023p-2ulr},
{0x1.16becd02p-1ulr, 0x1.d624031p-2ulr},
{0x1.0cf49fep-1ulr, 0x1.e743b844p-2ulr},
- {0x1.04214e9cp-1ulr, 0x1.f7ce2c3cp-2ulr},
+ {0x1.038cdfcp-1ulr, 0x1.f8e6408p-2ulr},
};
};
diff --git a/src/fcntl/fcntl.h b/src/fcntl/fcntl.h
new file mode 100644
index 000000000000..8fe3fb3146b9
--- /dev/null
+++ b/src/fcntl/fcntl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header of fcntl --------------------------*- 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_SRC_FCNTL_FCNTL_H
+#define LLVM_LIBC_SRC_FCNTL_FCNTL_H
+
+namespace LIBC_NAMESPACE {
+
+int fcntl(int fd, int cmd, ...);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_FCNTL_FCNTL_H
diff --git a/src/fcntl/linux/fcntl.cpp b/src/fcntl/linux/fcntl.cpp
new file mode 100644
index 000000000000..24a20fb36410
--- /dev/null
+++ b/src/fcntl/linux/fcntl.cpp
@@ -0,0 +1,93 @@
+//===-- Implementation of fcntl -------------------------------------------===//
+//
+// 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 "src/fcntl/fcntl.h"
+
+#include "hdr/fcntl_macros.h"
+#include "hdr/types/struct_f_owner_ex.h"
+#include "hdr/types/struct_flock.h"
+#include "hdr/types/struct_flock64.h"
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+#include "src/errno/libc_errno.h"
+
+#include <stdarg.h>
+#include <sys/syscall.h> // For syscall numbers.
+
+// The OFD file locks require special handling for LARGEFILES
+namespace LIBC_NAMESPACE {
+LLVM_LIBC_FUNCTION(int, fcntl, (int fd, int cmd, ...)) {
+ void *arg;
+ va_list varargs;
+ va_start(varargs, cmd);
+ arg = va_arg(varargs, void *);
+ va_end(varargs);
+
+ switch (cmd) {
+ case F_SETLKW:
+ return syscall_impl<int>(SYS_fcntl, fd, cmd, arg);
+ case F_OFD_SETLKW: {
+ struct flock *flk = reinterpret_cast<struct flock *>(arg);
+ // convert the struct to a flock64
+ struct flock64 flk64;
+ flk64.l_type = flk->l_type;
+ flk64.l_whence = flk->l_whence;
+ flk64.l_start = flk->l_start;
+ flk64.l_len = flk->l_len;
+ flk64.l_pid = flk->l_pid;
+ // create a syscall
+ return syscall_impl<int>(SYS_fcntl, fd, cmd, &flk64);
+ }
+ case F_OFD_GETLK:
+ case F_OFD_SETLK: {
+ struct flock *flk = reinterpret_cast<struct flock *>(arg);
+ // convert the struct to a flock64
+ struct flock64 flk64;
+ flk64.l_type = flk->l_type;
+ flk64.l_whence = flk->l_whence;
+ flk64.l_start = flk->l_start;
+ flk64.l_len = flk->l_len;
+ flk64.l_pid = flk->l_pid;
+ // create a syscall
+ int retVal = syscall_impl<int>(SYS_fcntl, fd, cmd, &flk64);
+ // On failure, return
+ if (retVal == -1)
+ return -1;
+ // Check for overflow, i.e. the offsets are not the same when cast
+ // to off_t from off64_t.
+ if (static_cast<off_t>(flk64.l_len) != flk64.l_len ||
+ static_cast<off_t>(flk64.l_start) != flk64.l_start) {
+ libc_errno = EOVERFLOW;
+ return -1;
+ }
+ // Now copy back into flk, in case flk64 got modified
+ flk->l_type = flk64.l_type;
+ flk->l_whence = flk64.l_whence;
+ flk->l_start = flk64.l_start;
+ flk->l_len = flk64.l_len;
+ flk->l_pid = flk64.l_pid;
+ return retVal;
+ }
+ case F_GETOWN: {
+ struct f_owner_ex fex;
+ int retVal = syscall_impl<int>(SYS_fcntl, fd, F_GETOWN_EX, &fex);
+ if (retVal == -EINVAL)
+ return syscall_impl<int>(SYS_fcntl, fd, cmd,
+ reinterpret_cast<void *>(arg));
+ if (static_cast<unsigned long>(retVal) <= -4096UL)
+ return fex.type == F_OWNER_PGRP ? -fex.pid : fex.pid;
+
+ libc_errno = -retVal;
+ return -1;
+ }
+ // The general case
+ default:
+ return syscall_impl<int>(SYS_fcntl, fd, cmd, reinterpret_cast<void *>(arg));
+ }
+}
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/nearbyintf128.cpp b/src/math/generic/nearbyintf128.cpp
new file mode 100644
index 000000000000..fca3587f5b58
--- /dev/null
+++ b/src/math/generic/nearbyintf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nearbyintf128 function --------------------------===//
+//
+// 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 "src/math/nearbyintf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, nearbyintf128, (float128 x)) {
+ return fputil::round_using_current_rounding_mode(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/generic/scalbnf128.cpp b/src/math/generic/scalbnf128.cpp
new file mode 100644
index 000000000000..be3d29ed27e9
--- /dev/null
+++ b/src/math/generic/scalbnf128.cpp
@@ -0,0 +1,27 @@
+//===-- Implementation of scalbnf128 function -----------------------------===//
+//
+// 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 "src/math/scalbnf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, scalbnf128, (float128 x, int n)) {
+// TODO: should be switched to use `FLT_RADIX` in hdr/float_macros.h" instead
+// see: https://github.com/llvm/llvm-project/issues/90496
+#if !defined(__FLT_RADIX__)
+#error __FLT_RADIX__ undefined.
+#elif __FLT_RADIX__ != 2
+#error __FLT_RADIX__!=2, unimplemented.
+#else
+ return fputil::ldexp(x, n);
+#endif
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/src/math/nearbyintf128.h b/src/math/nearbyintf128.h
new file mode 100644
index 000000000000..d12754a48100
--- /dev/null
+++ b/src/math/nearbyintf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for nearbyintf128 -----------------*- 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_SRC_MATH_NEARBYINTF128_H
+#define LLVM_LIBC_SRC_MATH_NEARBYINTF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 nearbyintf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEARBYINTF128_H
diff --git a/src/math/scalbnf128.h b/src/math/scalbnf128.h
new file mode 100644
index 000000000000..bd3b560fb7cc
--- /dev/null
+++ b/src/math/scalbnf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for scalbnf128 --------------------*- 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_SRC_MATH_SCALBNF128_H
+#define LLVM_LIBC_SRC_MATH_SCALBNF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 scalbnf128(float128 x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_SCALBNF128_H
diff --git a/test/UnitTest/FPMatcher.h b/test/UnitTest/FPMatcher.h
index a76e0b8ef6f6..c58c322c981e 100644
--- a/test/UnitTest/FPMatcher.h
+++ b/test/UnitTest/FPMatcher.h
@@ -219,4 +219,25 @@ template <typename T> struct FPTest : public Test {
} \
} while (0)
+#define EXPECT_FP_EQ_ROUNDING_MODE(expected, actual, rounding_mode) \
+ do { \
+ using namespace LIBC_NAMESPACE::fputil::testing; \
+ ForceRoundingMode __r((rounding_mode)); \
+ if (__r.success) { \
+ EXPECT_FP_EQ((expected), (actual)); \
+ } \
+ } while (0)
+
+#define EXPECT_FP_EQ_ROUNDING_NEAREST(expected, actual) \
+ EXPECT_FP_EQ_ROUNDING_MODE((expected), (actual), RoundingMode::Nearest)
+
+#define EXPECT_FP_EQ_ROUNDING_UPWARD(expected, actual) \
+ EXPECT_FP_EQ_ROUNDING_MODE((expected), (actual), RoundingMode::Upward)
+
+#define EXPECT_FP_EQ_ROUNDING_DOWNWARD(expected, actual) \
+ EXPECT_FP_EQ_ROUNDING_MODE((expected), (actual), RoundingMode::Downward)
+
+#define EXPECT_FP_EQ_ROUNDING_TOWARD_ZERO(expected, actual) \
+ EXPECT_FP_EQ_ROUNDING_MODE((expected), (actual), RoundingMode::TowardZero)
+
#endif // LLVM_LIBC_TEST_UNITTEST_FPMATCHER_H
diff --git a/test/src/fcntl/fcntl_test.cpp b/test/src/fcntl/fcntl_test.cpp
new file mode 100644
index 000000000000..c5cbb61b4ed8
--- /dev/null
+++ b/test/src/fcntl/fcntl_test.cpp
@@ -0,0 +1,155 @@
+//===-- Unittest for fcntl ------------------------------------------------===//
+//
+// 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 "hdr/fcntl_macros.h"
+#include "hdr/types/struct_flock.h"
+#include "src/errno/libc_errno.h"
+#include "src/fcntl/fcntl.h"
+#include "src/fcntl/open.h"
+#include "src/unistd/close.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include <stdio.h>
+#include <sys/stat.h> // For S_IRWXU
+
+TEST(LlvmLibcFcntlTest, FcntlDupfd) {
+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+ constexpr const char *TEST_FILE_NAME = "testdata/fcntl_dup.test";
+ auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
+ int fd2, fd3;
+ int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC, S_IRWXU);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(fd, 0);
+
+ fd2 = LIBC_NAMESPACE::fcntl(fd, F_DUPFD, 0);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(fd2, 0);
+
+ fd3 = LIBC_NAMESPACE::fcntl(fd, F_DUPFD, 10);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(fd3, 0);
+
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd2), Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd3), Succeeds(0));
+}
+
+TEST(LlvmLibcFcntlTest, FcntlGetFl) {
+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+ constexpr const char *TEST_FILE_NAME = "testdata/fcntl_getfl.test";
+ auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
+ int retVal;
+ int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC, S_IRWXU);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(fd, 0);
+
+ retVal = LIBC_NAMESPACE::fcntl(fd, F_GETFL);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(retVal, -1);
+
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+}
+
+TEST(LlvmLibcFcntlTest, FcntlSetFl) {
+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+ constexpr const char *TEST_FILE_NAME = "testdata/fcntl_setfl.test";
+ auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
+
+ int retVal;
+ int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(fd, 0);
+
+ retVal = LIBC_NAMESPACE::fcntl(fd, F_GETFL);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(retVal, -1);
+
+ int oldFlags = LIBC_NAMESPACE::fcntl(fd, F_GETFL, 0);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(oldFlags, 0);
+
+ // Add the APPEND flag;
+ oldFlags |= O_APPEND;
+
+ retVal = LIBC_NAMESPACE::fcntl(fd, F_SETFL, oldFlags);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(retVal, -1);
+
+ // Remove the APPEND flag;
+ oldFlags = -oldFlags & O_APPEND;
+
+ retVal = LIBC_NAMESPACE::fcntl(fd, F_SETFL, oldFlags);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(retVal, -1);
+
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+}
+
+TEST(LlvmLibcFcntlTest, FcntlGetLkRead) {
+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+ constexpr const char *TEST_FILE_NAME = "testdata/fcntl_getlkread.test";
+ auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
+
+ struct flock flk, svflk;
+ int retVal;
+ int fd =
+ LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDONLY, S_IRWXU);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(fd, 0);
+
+ flk.l_type = F_RDLCK;
+ flk.l_start = 0;
+ flk.l_whence = SEEK_SET;
+ flk.l_len = 50;
+
+ // copy flk into svflk
+ svflk = flk;
+
+ retVal = LIBC_NAMESPACE::fcntl(fd, F_GETLK, &svflk);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(retVal, -1);
+ ASSERT_NE((int)flk.l_type, F_WRLCK); // File should not be write locked.
+
+ retVal = LIBC_NAMESPACE::fcntl(fd, F_SETLK, &svflk);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(retVal, -1);
+
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+}
+
+TEST(LlvmLibcFcntlTest, FcntlGetLkWrite) {
+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+ constexpr const char *TEST_FILE_NAME = "testdata/fcntl_getlkwrite.test";
+ auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
+
+ struct flock flk, svflk;
+ int retVal;
+ int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(fd, 0);
+
+ flk.l_type = F_WRLCK;
+ flk.l_start = 0;
+ flk.l_whence = SEEK_SET;
+ flk.l_len = 0;
+
+ // copy flk into svflk
+ svflk = flk;
+
+ retVal = LIBC_NAMESPACE::fcntl(fd, F_GETLK, &svflk);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(retVal, -1);
+ ASSERT_NE((int)flk.l_type, F_RDLCK); // File should not be read locked.
+
+ retVal = LIBC_NAMESPACE::fcntl(fd, F_SETLK, &svflk);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(retVal, -1);
+
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+}
diff --git a/test/src/math/scalbnf128_test.cpp b/test/src/math/scalbnf128_test.cpp
new file mode 100644
index 000000000000..dc259de21148
--- /dev/null
+++ b/test/src/math/scalbnf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for scalbnf128 ------------------------------------------===//
+//
+// 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 "ScalbnTest.h"
+
+#include "src/math/scalbnf128.h"
+
+LIST_SCALBN_TESTS(float128, LIBC_NAMESPACE::scalbnf128)
diff --git a/test/src/math/smoke/NearbyIntTest.h b/test/src/math/smoke/NearbyIntTest.h
new file mode 100644
index 000000000000..0051ff9447a7
--- /dev/null
+++ b/test/src/math/smoke/NearbyIntTest.h
@@ -0,0 +1,100 @@
+//===-- Utility class to test different flavors of nearbyint ----*- 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_TEST_SRC_MATH_NEARBYINTTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_NEARBYINTTEST_H
+
+#include "hdr/fenv_macros.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+static constexpr int ROUNDING_MODES[4] = {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO,
+ FE_TONEAREST};
+
+template <typename T>
+class NearbyIntTestTemplate : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*NearbyIntFunc)(T);
+
+ void testNaN(NearbyIntFunc func) {
+ EXPECT_FP_EQ_ALL_ROUNDING(func(aNaN), aNaN);
+ }
+
+ void testInfinities(NearbyIntFunc func) {
+ EXPECT_FP_EQ_ALL_ROUNDING(func(inf), inf);
+ EXPECT_FP_EQ_ALL_ROUNDING(func(neg_inf), neg_inf);
+ }
+
+ void testZeroes(NearbyIntFunc func) {
+ EXPECT_FP_EQ_ALL_ROUNDING(func(zero), zero);
+ EXPECT_FP_EQ_ALL_ROUNDING(func(neg_zero), neg_zero);
+ }
+
+ void testIntegers(NearbyIntFunc func) {
+ EXPECT_FP_EQ_ALL_ROUNDING(func(T(1.0)), T(1.0));
+ EXPECT_FP_EQ_ALL_ROUNDING(func(T(-1.0)), T(-1.0));
+
+ EXPECT_FP_EQ_ALL_ROUNDING(func(T(1234.0)), T(1234.0));
+ EXPECT_FP_EQ_ALL_ROUNDING(func(T(-1234.0)), T(-1234.0));
+
+ EXPECT_FP_EQ_ALL_ROUNDING(func(T(10.0)), T(10.0));
+ EXPECT_FP_EQ_ALL_ROUNDING(func(T(-10.0)), T(-10.0));
+
+ FPBits ints_start(T(0));
+ ints_start.set_biased_exponent(FPBits::SIG_LEN + FPBits::EXP_BIAS);
+ T expected = ints_start.get_val();
+ EXPECT_FP_EQ_ALL_ROUNDING(func(expected), expected);
+ }
+
+ void testSubnormalToNearest(NearbyIntFunc func) {
+ ASSERT_FP_EQ(func(min_denormal), zero);
+ ASSERT_FP_EQ(func(-min_denormal), neg_zero);
+ }
+
+ void testSubnormalTowardZero(NearbyIntFunc func) {
+ EXPECT_FP_EQ_ROUNDING_TOWARD_ZERO(func(min_denormal), zero);
+ EXPECT_FP_EQ_ROUNDING_TOWARD_ZERO(func(-min_denormal), neg_zero);
+ }
+
+ void testSubnormalToPosInf(NearbyIntFunc func) {
+ EXPECT_FP_EQ_ROUNDING_UPWARD(func(min_denormal), FPBits::one().get_val());
+ EXPECT_FP_EQ_ROUNDING_UPWARD(func(-min_denormal), neg_zero);
+ }
+
+ void testSubnormalToNegInf(NearbyIntFunc func) {
+ T negative_one = FPBits::one(Sign::NEG).get_val();
+ EXPECT_FP_EQ_ROUNDING_DOWNWARD(func(min_denormal), zero);
+ EXPECT_FP_EQ_ROUNDING_DOWNWARD(func(-min_denormal), negative_one);
+ }
+};
+
+#define LIST_NEARBYINT_TESTS(T, func) \
+ using LlvmLibcNearbyIntTest = NearbyIntTestTemplate<T>; \
+ TEST_F(LlvmLibcNearbyIntTest, TestNaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcNearbyIntTest, TestInfinities) { testInfinities(&func); } \
+ TEST_F(LlvmLibcNearbyIntTest, TestZeroes) { testZeroes(&func); } \
+ TEST_F(LlvmLibcNearbyIntTest, TestIntegers) { testIntegers(&func); } \
+ TEST_F(LlvmLibcNearbyIntTest, TestSubnormalToNearest) { \
+ testSubnormalToNearest(&func); \
+ } \
+ TEST_F(LlvmLibcNearbyIntTest, TestSubnormalTowardZero) { \
+ testSubnormalTowardZero(&func); \
+ } \
+ TEST_F(LlvmLibcNearbyIntTest, TestSubnormalToPosInf) { \
+ testSubnormalToPosInf(&func); \
+ } \
+ TEST_F(LlvmLibcNearbyIntTest, TestSubnormalToNegInf) { \
+ testSubnormalToNegInf(&func); \
+ }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_NEARBYINTTEST_H
diff --git a/test/src/math/smoke/nearbyint_test.cpp b/test/src/math/smoke/nearbyint_test.cpp
new file mode 100644
index 000000000000..11a5c3372e73
--- /dev/null
+++ b/test/src/math/smoke/nearbyint_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nearbyint -------------------------------------------===//
+//
+// 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 "NearbyIntTest.h"
+
+#include "src/math/nearbyint.h"
+
+LIST_NEARBYINT_TESTS(double, LIBC_NAMESPACE::nearbyint)
diff --git a/test/src/math/smoke/nearbyintf128_test.cpp b/test/src/math/smoke/nearbyintf128_test.cpp
new file mode 100644
index 000000000000..98fbb2858faf
--- /dev/null
+++ b/test/src/math/smoke/nearbyintf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nearbyintf128 ---------------------------------------===//
+//
+// 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 "NearbyIntTest.h"
+
+#include "src/math/nearbyintf128.h"
+
+LIST_NEARBYINT_TESTS(float128, LIBC_NAMESPACE::nearbyintf128)
diff --git a/test/src/math/smoke/nearbyintf_test.cpp b/test/src/math/smoke/nearbyintf_test.cpp
new file mode 100644
index 000000000000..fd26153cfffb
--- /dev/null
+++ b/test/src/math/smoke/nearbyintf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nearbyintf ------------------------------------------===//
+//
+// 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 "NearbyIntTest.h"
+
+#include "src/math/nearbyintf.h"
+
+LIST_NEARBYINT_TESTS(float, LIBC_NAMESPACE::nearbyintf)
diff --git a/test/src/math/smoke/nearbyintl_test.cpp b/test/src/math/smoke/nearbyintl_test.cpp
new file mode 100644
index 000000000000..a6d81a1439e1
--- /dev/null
+++ b/test/src/math/smoke/nearbyintl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nearbyintl ------------------------------------------===//
+//
+// 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 "NearbyIntTest.h"
+
+#include "src/math/nearbyintl.h"
+
+LIST_NEARBYINT_TESTS(long double, LIBC_NAMESPACE::nearbyintl)
diff --git a/test/src/math/smoke/scalbnf128_test.cpp b/test/src/math/smoke/scalbnf128_test.cpp
new file mode 100644
index 000000000000..dc259de21148
--- /dev/null
+++ b/test/src/math/smoke/scalbnf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for scalbnf128 ------------------------------------------===//
+//
+// 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 "ScalbnTest.h"
+
+#include "src/math/scalbnf128.h"
+
+LIST_SCALBN_TESTS(float128, LIBC_NAMESPACE::scalbnf128)
diff --git a/test/src/stdfix/ISqrtTest.h b/test/src/stdfix/ISqrtTest.h
index 405162b706a9..ddf292fdd083 100644
--- a/test/src/stdfix/ISqrtTest.h
+++ b/test/src/stdfix/ISqrtTest.h
@@ -27,6 +27,18 @@ template <typename T> class ISqrtTest : public LIBC_NAMESPACE::testing::Test {
public:
typedef OutType (*SqrtFunc)(T);
+ void testSpecificInput(T input, OutType result, double expected,
+ double tolerance) {
+ double y_d = static_cast<double>(result);
+ double errors = LIBC_NAMESPACE::fputil::abs((y_d / expected) - 1.0);
+ if (errors > tolerance) {
+ // Print out the failure input and output.
+ EXPECT_EQ(input, T(0));
+ EXPECT_EQ(result, zero);
+ }
+ ASSERT_TRUE(errors <= tolerance);
+ }
+
void testSpecialNumbers(SqrtFunc func) {
EXPECT_EQ(zero, func(T(0)));
@@ -42,15 +54,9 @@ public:
for (int i = 0; i < COUNT; ++i) {
x_d += 1.0;
++x;
- double y_d = static_cast<double>(func(x));
- double result = LIBC_NAMESPACE::fputil::sqrt(x_d);
- double errors = LIBC_NAMESPACE::fputil::abs((y_d / result) - 1.0);
- if (errors > ERR) {
- // Print out the failure input and output.
- EXPECT_EQ(x, T(0));
- EXPECT_EQ(func(x), zero);
- }
- ASSERT_TRUE(errors <= ERR);
+ OutType result = func(x);
+ double expected = LIBC_NAMESPACE::fputil::sqrt(x_d);
+ testSpecificInput(x, result, expected, ERR);
}
}
};
diff --git a/test/src/stdfix/SqrtTest.h b/test/src/stdfix/SqrtTest.h
index 628be0deb770..47ec129fab2a 100644
--- a/test/src/stdfix/SqrtTest.h
+++ b/test/src/stdfix/SqrtTest.h
@@ -42,7 +42,7 @@ public:
constexpr size_t COUNT = 255;
constexpr StorageType STEP =
- ~StorageType(0) / static_cast<StorageType>(COUNT);
+ StorageType(~StorageType(0)) / static_cast<StorageType>(COUNT);
constexpr double ERR = 3.0 * static_cast<double>(eps);
StorageType x = 0;
for (size_t i = 0; i < COUNT; ++i, x += STEP) {
diff --git a/test/src/stdfix/uksqrtui_test.cpp b/test/src/stdfix/uksqrtui_test.cpp
index 0f4c057099da..c336d0ce1f61 100644
--- a/test/src/stdfix/uksqrtui_test.cpp
+++ b/test/src/stdfix/uksqrtui_test.cpp
@@ -17,4 +17,13 @@ unsigned accum uksqrtui_fast(unsigned int x) {
LIST_ISQRT_TESTS(UI, unsigned int, LIBC_NAMESPACE::uksqrtui);
+TEST_F(LlvmLibcISqrtUITest, LargeInteger) {
+ testSpecificInput(65529u, LIBC_NAMESPACE::uksqrtui(65529u), 0x1.fff8fep7,
+ 0x3.0p-16);
+}
+
LIST_ISQRT_TESTS(UIFast, unsigned int, uksqrtui_fast);
+
+TEST_F(LlvmLibcISqrtUIFastTest, LargeInteger) {
+ testSpecificInput(65529u, uksqrtui_fast(65529u), 0x1.fff8fep7, 0x3.0p-16);
+}