[libc-commits] [libc] c5cfbe4 - [libc] Skip fenv exception tests on aarch64 if HW doesn't support exceptions.

Siva Chandra Reddy via libc-commits libc-commits at lists.llvm.org
Thu Sep 9 13:48:08 PDT 2021


Author: Siva Chandra Reddy
Date: 2021-09-09T20:47:59Z
New Revision: c5cfbe40de6ef3eb7958cffdd9eee2eb8b6c77b9

URL: https://github.com/llvm/llvm-project/commit/c5cfbe40de6ef3eb7958cffdd9eee2eb8b6c77b9
DIFF: https://github.com/llvm/llvm-project/commit/c5cfbe40de6ef3eb7958cffdd9eee2eb8b6c77b9.diff

LOG: [libc] Skip fenv exception tests on aarch64 if HW doesn't support exceptions.

Reviewed By: michaelrj

Differential Revision: https://reviews.llvm.org/D109538

Added: 
    

Modified: 
    libc/src/__support/FPUtil/aarch64/FEnvImpl.h
    libc/src/__support/FPUtil/x86_64/FEnvImpl.h
    libc/test/src/fenv/enabled_exceptions_test.cpp
    libc/test/src/fenv/feholdexcept_test.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/FPUtil/aarch64/FEnvImpl.h b/libc/src/__support/FPUtil/aarch64/FEnvImpl.h
index 950824631a253..36d6caaab5ba9 100644
--- a/libc/src/__support/FPUtil/aarch64/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/aarch64/FEnvImpl.h
@@ -89,6 +89,13 @@ static inline int disableExcept(int excepts) {
   return FEnv::exceptionStatusToMacro(oldExcepts);
 }
 
+static inline int getExcept() {
+  uint32_t controlWord = FEnv::getControlWord();
+  int enabledExcepts =
+      (controlWord >> FEnv::ExceptionControlFlagsBitPosition) & 0x1F;
+  return FEnv::exceptionStatusToMacro(enabledExcepts);
+}
+
 static inline int clearExcept(int excepts) {
   uint32_t statusWord = FEnv::getStatusWord();
   uint32_t toClear = FEnv::getStatusValueForExcept(excepts);

diff  --git a/libc/src/__support/FPUtil/x86_64/FEnvImpl.h b/libc/src/__support/FPUtil/x86_64/FEnvImpl.h
index 88623b90aaa8e..d5bb703cebafa 100644
--- a/libc/src/__support/FPUtil/x86_64/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/x86_64/FEnvImpl.h
@@ -187,6 +187,12 @@ static inline int disableExcept(int excepts) {
   return internal::exceptionStatusToMacro(oldExcepts);
 }
 
+static inline int getExcept() {
+  uint16_t x87CW = internal::getX87ControlWord();
+  uint16_t enabledExcepts = ~x87CW & 0x3F;
+  return internal::exceptionStatusToMacro(enabledExcepts);
+}
+
 static inline int clearExcept(int excepts) {
   internal::X87StateDescriptor state;
   internal::getX87StateDescriptor(state);

diff  --git a/libc/test/src/fenv/enabled_exceptions_test.cpp b/libc/test/src/fenv/enabled_exceptions_test.cpp
index 3d2b02f776590..b971e717beed4 100644
--- a/libc/test/src/fenv/enabled_exceptions_test.cpp
+++ b/libc/test/src/fenv/enabled_exceptions_test.cpp
@@ -20,6 +20,20 @@
 // This test enables an exception and verifies that raising that exception
 // triggers SIGFPE.
 TEST(LlvmLibcExceptionStatusTest, RaiseAndCrash) {
+#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::fputil::disableExcept(FE_ALL_EXCEPT);
+  __llvm_libc::fputil::enableExcept(FE_DIVBYZERO);
+  if (__llvm_libc::fputil::getExcept() == 0)
+    return;
+#endif
+
   // TODO: Install a floating point exception handler and verify that the
   // the expected exception was raised. One will have to longjmp back from
   // that exception handler, so such a testing can be done after we have

diff  --git a/libc/test/src/fenv/feholdexcept_test.cpp b/libc/test/src/fenv/feholdexcept_test.cpp
index 5233e1b572c70..3f8401f1bc781 100644
--- a/libc/test/src/fenv/feholdexcept_test.cpp
+++ b/libc/test/src/fenv/feholdexcept_test.cpp
@@ -15,6 +15,20 @@
 #include <fenv.h>
 
 TEST(LlvmLibcFEnvTest, RaiseAndCrash) {
+#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::fputil::disableExcept(FE_ALL_EXCEPT);
+  __llvm_libc::fputil::enableExcept(FE_DIVBYZERO);
+  if (__llvm_libc::fputil::getExcept() == 0)
+    return;
+#endif
+
   int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
                    FE_UNDERFLOW};
 


        


More information about the libc-commits mailing list