[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