diff --git a/libc/src/__support/FPUtil/aarch64/FEnvImpl.h b/libc/src/__support/FPUtil/aarch64/FEnvImpl.h --- a/libc/src/__support/FPUtil/aarch64/FEnvImpl.h +++ b/libc/src/__support/FPUtil/aarch64/FEnvImpl.h @@ -118,7 +118,7 @@ } static inline int set_except(int excepts) { - uint32_t statusWord = FEnv::getControlWord(); + uint32_t statusWord = FEnv::getStatusWord(); uint32_t statusValue = FEnv::getStatusValueForExcept(excepts); statusWord |= (statusValue << FEnv::ExceptionStatusFlagsBitPosition); FEnv::writeStatusWord(statusWord); @@ -140,13 +140,14 @@ }; uint32_t toRaise = FEnv::getStatusValueForExcept(excepts); + int result = 0; if (toRaise & FEnv::INVALID) { divfunc(zero, zero); uint32_t statusWord = FEnv::getStatusWord(); if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) & FEnv::INVALID)) - return -1; + result = -1; } if (toRaise & FEnv::DIVBYZERO) { @@ -154,21 +155,21 @@ uint32_t statusWord = FEnv::getStatusWord(); if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) & FEnv::DIVBYZERO)) - return -1; + result = -1; } if (toRaise & FEnv::OVERFLOW) { divfunc(largeValue, smallValue); uint32_t statusWord = FEnv::getStatusWord(); if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) & FEnv::OVERFLOW)) - return -1; + result = -1; } if (toRaise & FEnv::UNDERFLOW) { divfunc(smallValue, largeValue); uint32_t statusWord = FEnv::getStatusWord(); if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) & FEnv::UNDERFLOW)) - return -1; + result = -1; } if (toRaise & FEnv::INEXACT) { float two = 2.0f; @@ -179,9 +180,9 @@ uint32_t statusWord = FEnv::getStatusWord(); if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) & FEnv::INEXACT)) - return -1; + result = -1; } - return 0; + return result; } static inline int get_round() { diff --git a/libc/test/src/fenv/feclearexcept_test.cpp b/libc/test/src/fenv/feclearexcept_test.cpp --- a/libc/test/src/fenv/feclearexcept_test.cpp +++ b/libc/test/src/fenv/feclearexcept_test.cpp @@ -24,56 +24,17 @@ ASSERT_EQ(__llvm_libc::fputil::test_except(e), 0); __llvm_libc::fputil::raise_except(FE_ALL_EXCEPT); - for (uint16_t e : excepts) { - // We clear one exception and test to verify that it was cleared. - __llvm_libc::feclearexcept(e); - ASSERT_EQ(uint16_t(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT)), - uint16_t(FE_ALL_EXCEPT & ~e)); - // After clearing, we raise the exception again. - __llvm_libc::fputil::raise_except(e); - } - - for (uint16_t e1 : excepts) { - for (uint16_t e2 : excepts) { - __llvm_libc::feclearexcept(e1 | e2); - ASSERT_EQ(uint16_t(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT)), - uint16_t(FE_ALL_EXCEPT & ~(e1 | e2))); - __llvm_libc::fputil::raise_except(e1 | e2); - } - } - - for (uint16_t e1 : excepts) { - for (uint16_t e2 : excepts) { - for (uint16_t e3 : excepts) { - __llvm_libc::feclearexcept(e1 | e2 | e3); - ASSERT_EQ(uint16_t(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT)), - uint16_t(FE_ALL_EXCEPT & ~(e1 | e2 | e3))); - __llvm_libc::fputil::raise_except(e1 | e2 | e3); - } - } - } - - for (uint16_t e1 : excepts) { - for (uint16_t e2 : excepts) { - for (uint16_t e3 : excepts) { - for (uint16_t e4 : excepts) { - __llvm_libc::feclearexcept(e1 | e2 | e3 | e4); - ASSERT_EQ(uint16_t(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT)), - uint16_t(FE_ALL_EXCEPT & ~(e1 | e2 | e3 | e4))); - __llvm_libc::fputil::raise_except(e1 | e2 | e3 | e4); - } - } - } - } for (uint16_t e1 : excepts) { for (uint16_t e2 : excepts) { for (uint16_t e3 : excepts) { for (uint16_t e4 : excepts) { for (uint16_t e5 : excepts) { + // We clear one exception and test to verify that it was cleared. __llvm_libc::feclearexcept(e1 | e2 | e3 | e4 | e5); - ASSERT_EQ(uint16_t(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT)), - uint16_t(FE_ALL_EXCEPT & ~(e1 | e2 | e3 | e4 | e5))); + ASSERT_EQ(__llvm_libc::fputil::test_except(e1 | e2 | e3 | e4 | e5), + 0); + // After clearing, we raise the exception again. __llvm_libc::fputil::raise_except(e1 | e2 | e3 | e4 | e5); } }