[libc-commits] [libc] 0da5ac1 - [libc] Add extension functions fedisableexcept, feenableexcept and fegetexcept.
Siva Chandra Reddy via libc-commits
libc-commits at lists.llvm.org
Fri Sep 10 11:45:03 PDT 2021
Author: Siva Chandra Reddy
Date: 2021-09-10T18:44:53Z
New Revision: 0da5ac1a7537f05d6ca87ec2e76b25f3b555c301
URL: https://github.com/llvm/llvm-project/commit/0da5ac1a7537f05d6ca87ec2e76b25f3b555c301
DIFF: https://github.com/llvm/llvm-project/commit/0da5ac1a7537f05d6ca87ec2e76b25f3b555c301.diff
LOG: [libc] Add extension functions fedisableexcept, feenableexcept and fegetexcept.
Reviewed By: michaelrj
Differential Revision: https://reviews.llvm.org/D109613
Added:
libc/src/fenv/fedisableexcept.cpp
libc/src/fenv/fedisableexcept.h
libc/src/fenv/feenableexcept.cpp
libc/src/fenv/feenableexcept.h
libc/src/fenv/fegetexcept.cpp
libc/src/fenv/fegetexcept.h
libc/test/src/fenv/feenableexcept_test.cpp
Modified:
libc/config/linux/aarch64/entrypoints.txt
libc/config/linux/x86_64/entrypoints.txt
libc/spec/gnu_ext.td
libc/src/fenv/CMakeLists.txt
libc/test/src/fenv/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index f8347678038a9..8dbbb64abbd60 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -62,7 +62,10 @@ set(TARGET_LIBC_ENTRYPOINTS
set(TARGET_LIBM_ENTRYPOINTS
# fenv.h entrypoints
libc.src.fenv.feclearexcept
+ libc.src.fenv.fedisableexcept
+ libc.src.fenv.feenableexcept
libc.src.fenv.fegetenv
+ libc.src.fenv.fegetexcept
libc.src.fenv.fegetexceptflag
libc.src.fenv.fegetround
libc.src.fenv.feholdexcept
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 59c5f5100f691..9836d62f89042 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -62,7 +62,10 @@ set(TARGET_LIBC_ENTRYPOINTS
set(TARGET_LIBM_ENTRYPOINTS
# fenv.h entrypoints
libc.src.fenv.feclearexcept
+ libc.src.fenv.fedisableexcept
+ libc.src.fenv.feenableexcept
libc.src.fenv.fegetenv
+ libc.src.fenv.fegetexcept
libc.src.fenv.fegetexceptflag
libc.src.fenv.fegetround
libc.src.fenv.feholdexcept
diff --git a/libc/spec/gnu_ext.td b/libc/spec/gnu_ext.td
index 0b0b8ca38c400..99b78deed28b4 100644
--- a/libc/spec/gnu_ext.td
+++ b/libc/spec/gnu_ext.td
@@ -41,9 +41,33 @@ def GnuExtensions : StandardSpec<"GNUExtensions"> {
]
>;
+ HeaderSpec FEnv = HeaderSpec<
+ "fenv.h",
+ [], // Macros
+ [], // Types
+ [], // Enumerations
+ [
+ FunctionSpec<
+ "fedisableexcept",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>]
+ >,
+ FunctionSpec<
+ "feenableexcept",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>]
+ >,
+ FunctionSpec<
+ "fegetexcept",
+ RetValSpec<IntType>,
+ []
+ >
+ ]
+ >;
let Headers = [
CType,
+ FEnv,
Math,
String,
];
diff --git a/libc/src/fenv/CMakeLists.txt b/libc/src/fenv/CMakeLists.txt
index ea3946be70fb0..2a210c026dac3 100644
--- a/libc/src/fenv/CMakeLists.txt
+++ b/libc/src/fenv/CMakeLists.txt
@@ -140,3 +140,42 @@ add_entrypoint_object(
COMPILE_OPTIONS
-O2
)
+
+add_entrypoint_object(
+ feenableexcept
+ SRCS
+ feenableexcept.cpp
+ HDRS
+ feenableexcept.h
+ DEPENDS
+ libc.include.fenv
+ libc.src.__support.FPUtil.fputil
+ COMPILE_OPTIONS
+ -O2
+)
+
+add_entrypoint_object(
+ fedisableexcept
+ SRCS
+ fedisableexcept.cpp
+ HDRS
+ fedisableexcept.h
+ DEPENDS
+ libc.include.fenv
+ libc.src.__support.FPUtil.fputil
+ COMPILE_OPTIONS
+ -O2
+)
+
+add_entrypoint_object(
+ fegetexcept
+ SRCS
+ fegetexcept.cpp
+ HDRS
+ fegetexcept.h
+ DEPENDS
+ libc.include.fenv
+ libc.src.__support.FPUtil.fputil
+ COMPILE_OPTIONS
+ -O2
+)
diff --git a/libc/src/fenv/fedisableexcept.cpp b/libc/src/fenv/fedisableexcept.cpp
new file mode 100644
index 0000000000000..a31bb947f4612
--- /dev/null
+++ b/libc/src/fenv/fedisableexcept.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of fedisableexcept 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/fenv/fedisableexcept.h"
+#include "src/__support/FPUtil/FEnvUtils.h"
+#include "src/__support/common.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, fedisableexcept, (int e)) {
+ return fputil::disableExcept(e);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/fenv/fedisableexcept.h b/libc/src/fenv/fedisableexcept.h
new file mode 100644
index 0000000000000..44a545edb7a92
--- /dev/null
+++ b/libc/src/fenv/fedisableexcept.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fedisableexcept ---------------*- 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_FENV_FEDISABLEEXCEPT_H
+#define LLVM_LIBC_SRC_FENV_FEDISABLEEXCEPT_H
+
+namespace __llvm_libc {
+
+int fedisableexcept(int);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_FENV_FEDISABLEEXCEPT_H
diff --git a/libc/src/fenv/feenableexcept.cpp b/libc/src/fenv/feenableexcept.cpp
new file mode 100644
index 0000000000000..1046babc31fce
--- /dev/null
+++ b/libc/src/fenv/feenableexcept.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of feenableexcept 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/fenv/feenableexcept.h"
+#include "src/__support/FPUtil/FEnvUtils.h"
+#include "src/__support/common.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, feenableexcept, (int e)) {
+ return fputil::enableExcept(e);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/fenv/feenableexcept.h b/libc/src/fenv/feenableexcept.h
new file mode 100644
index 0000000000000..58c1e0a9a4a46
--- /dev/null
+++ b/libc/src/fenv/feenableexcept.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for feenableexcept ----------------*- 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_FENV_FEENABLEEXCEPT_H
+#define LLVM_LIBC_SRC_FENV_FEENABLEEXCEPT_H
+
+namespace __llvm_libc {
+
+int feenableexcept(int);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_FENV_FEENABLEEXCEPT_H
diff --git a/libc/src/fenv/fegetexcept.cpp b/libc/src/fenv/fegetexcept.cpp
new file mode 100644
index 0000000000000..1c9ec376fcf22
--- /dev/null
+++ b/libc/src/fenv/fegetexcept.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of fegetexcept 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/fenv/fegetexcept.h"
+#include "src/__support/FPUtil/FEnvUtils.h"
+#include "src/__support/common.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, fegetexcept, ()) { return fputil::getExcept(); }
+
+} // namespace __llvm_libc
diff --git a/libc/src/fenv/fegetexcept.h b/libc/src/fenv/fegetexcept.h
new file mode 100644
index 0000000000000..ed6579f8f4671
--- /dev/null
+++ b/libc/src/fenv/fegetexcept.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fegetexcept -------------------*- 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_FENV_FEGETEXCEPT_H
+#define LLVM_LIBC_SRC_FENV_FEGETEXCEPT_H
+
+namespace __llvm_libc {
+
+int fegetexcept();
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_FENV_FEGETEXCEPT_H
diff --git a/libc/test/src/fenv/CMakeLists.txt b/libc/test/src/fenv/CMakeLists.txt
index 64f43fac34f75..bab83c1138e4c 100644
--- a/libc/test/src/fenv/CMakeLists.txt
+++ b/libc/test/src/fenv/CMakeLists.txt
@@ -71,6 +71,18 @@ add_libc_unittest(
libc.src.__support.FPUtil.fputil
)
+add_libc_unittest(
+ feenableexcept_test
+ SUITE
+ libc_fenv_unittests
+ SRCS
+ feenableexcept_test.cpp
+ DEPENDS
+ libc.src.fenv.fedisableexcept
+ libc.src.fenv.feenableexcept
+ libc.src.fenv.fegetexcept
+)
+
if (NOT (LLVM_USE_SANITIZER OR (${LIBC_TARGET_OS} STREQUAL "windows")))
# Sanitizers don't like SIGFPE. So, we will run the
# tests which raise SIGFPE only in non-sanitizer builds.
diff --git a/libc/test/src/fenv/feenableexcept_test.cpp b/libc/test/src/fenv/feenableexcept_test.cpp
new file mode 100644
index 0000000000000..2158f954bcd2b
--- /dev/null
+++ b/libc/test/src/fenv/feenableexcept_test.cpp
@@ -0,0 +1,86 @@
+//===-- Unittests for feenableexcept -------------------------------------===//
+//
+// 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/fenv/fedisableexcept.h"
+#include "src/fenv/feenableexcept.h"
+#include "src/fenv/fegetexcept.h"
+
+#include "utils/UnitTest/Test.h"
+
+#include <fenv.h>
+
+TEST(LlvmLibcFEnvTest, EnableTest) {
+#ifdef __aarch64__
+ // Few aarch64 HW implementations do not trap exceptions. We skip this test
+ // completely on such HW.
+ //
+ // Whether HW supports trapping exceptions or not is deduced by enabling an
+ // exception and reading back to see if the exception got enabled. If the
+ // exception did not get enabled, then it means that the HW does not support
+ // trapping exceptions.
+ __llvm_libc::fedisableexcept(FE_ALL_EXCEPT);
+ __llvm_libc::feenableexcept(FE_DIVBYZERO);
+ if (__llvm_libc::fegetexcept() == 0)
+ return;
+#endif
+
+ int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
+ FE_UNDERFLOW};
+ __llvm_libc::fedisableexcept(FE_ALL_EXCEPT);
+ ASSERT_EQ(0, __llvm_libc::fegetexcept());
+
+ for (int e : excepts) {
+ __llvm_libc::feenableexcept(e);
+ ASSERT_EQ(e, __llvm_libc::fegetexcept());
+ __llvm_libc::fedisableexcept(e);
+ }
+
+ for (int e1 : excepts) {
+ for (int e2 : excepts) {
+ __llvm_libc::feenableexcept(e1 | e2);
+ ASSERT_EQ(e1 | e2, __llvm_libc::fegetexcept());
+ __llvm_libc::fedisableexcept(e1 | e2);
+ }
+ }
+
+ for (int e1 : excepts) {
+ for (int e2 : excepts) {
+ for (int e3 : excepts) {
+ __llvm_libc::feenableexcept(e1 | e2 | e3);
+ ASSERT_EQ(e1 | e2 | e3, __llvm_libc::fegetexcept());
+ __llvm_libc::fedisableexcept(e1 | e2 | e3);
+ }
+ }
+ }
+
+ for (int e1 : excepts) {
+ for (int e2 : excepts) {
+ for (int e3 : excepts) {
+ for (int e4 : excepts) {
+ __llvm_libc::feenableexcept(e1 | e2 | e3 | e4);
+ ASSERT_EQ(e1 | e2 | e3 | e4, __llvm_libc::fegetexcept());
+ __llvm_libc::fedisableexcept(e1 | e2 | e3 | e4);
+ }
+ }
+ }
+ }
+
+ for (int e1 : excepts) {
+ for (int e2 : excepts) {
+ for (int e3 : excepts) {
+ for (int e4 : excepts) {
+ for (int e5 : excepts) {
+ __llvm_libc::feenableexcept(e1 | e2 | e3 | e4 | e5);
+ ASSERT_EQ(e1 | e2 | e3 | e4 | e5, __llvm_libc::fegetexcept());
+ __llvm_libc::fedisableexcept(e1 | e2 | e3 | e4 | e5);
+ }
+ }
+ }
+ }
+ }
+}
More information about the libc-commits
mailing list