[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