[flang-commits] [flang] 2ebf4b6 - [flang] Fix setting mxcsr on MSVC
Isuru Fernando via flang-commits
flang-commits at lists.llvm.org
Wed Jul 8 05:25:31 PDT 2020
Author: Isuru Fernando
Date: 2020-07-08T07:25:25-05:00
New Revision: 2ebf4b6e4c35c93c97da9ed14db7b38757c0d7f9
URL: https://github.com/llvm/llvm-project/commit/2ebf4b6e4c35c93c97da9ed14db7b38757c0d7f9
DIFF: https://github.com/llvm/llvm-project/commit/2ebf4b6e4c35c93c97da9ed14db7b38757c0d7f9.diff
LOG: [flang] Fix setting mxcsr on MSVC
Reviewers: sscalpone, jdoerfert, #flang, DavidTruby, jeanPerier
Reviewed By: jeanPerier
Subscribers: richard.barton.arm, jeanPerier, ro, llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D77815
Added:
Modified:
flang/lib/Evaluate/host.cpp
flang/lib/Evaluate/host.h
flang/unittests/Evaluate/fp-testing.cpp
flang/unittests/Evaluate/fp-testing.h
Removed:
################################################################################
diff --git a/flang/lib/Evaluate/host.cpp b/flang/lib/Evaluate/host.cpp
index ea831274b942..c9aa5c4bbce3 100644
--- a/flang/lib/Evaluate/host.cpp
+++ b/flang/lib/Evaluate/host.cpp
@@ -11,6 +11,9 @@
#include "flang/Common/idioms.h"
#include "llvm/Support/Errno.h"
#include <cfenv>
+#if __x86_64__
+#include <xmmintrin.h>
+#endif
namespace Fortran::evaluate::host {
using namespace Fortran::parser::literals;
@@ -18,39 +21,42 @@ using namespace Fortran::parser::literals;
void HostFloatingPointEnvironment::SetUpHostFloatingPointEnvironment(
FoldingContext &context) {
errno = 0;
+ std::fenv_t currentFenv;
if (feholdexcept(&originalFenv_) != 0) {
common::die("Folding with host runtime: feholdexcept() failed: %s",
llvm::sys::StrError(errno).c_str());
return;
}
- if (fegetenv(¤tFenv_) != 0) {
+ if (fegetenv(¤tFenv) != 0) {
common::die("Folding with host runtime: fegetenv() failed: %s",
llvm::sys::StrError(errno).c_str());
return;
}
#if __x86_64__
hasSubnormalFlushingHardwareControl_ = true;
+ originalMxcsr = _mm_getcsr();
+ unsigned int currentMxcsr{originalMxcsr};
if (context.flushSubnormalsToZero()) {
- currentFenv_.__mxcsr |= 0x8000; // result
- currentFenv_.__mxcsr |= 0x0040; // operands
+ currentMxcsr |= 0x8000;
+ currentMxcsr |= 0x0040;
} else {
- currentFenv_.__mxcsr &= ~0x8000; // result
- currentFenv_.__mxcsr &= ~0x0040; // operands
+ currentMxcsr &= ~0x8000;
+ currentMxcsr &= ~0x0040;
}
#elif defined(__aarch64__)
#if defined(__GNU_LIBRARY__)
hasSubnormalFlushingHardwareControl_ = true;
if (context.flushSubnormalsToZero()) {
- currentFenv_.__fpcr |= (1U << 24); // control register
+ currentFenv.__fpcr |= (1U << 24); // control register
} else {
- currentFenv_.__fpcr &= ~(1U << 24); // control register
+ currentFenv.__fpcr &= ~(1U << 24); // control register
}
#elif defined(__BIONIC__)
hasSubnormalFlushingHardwareControl_ = true;
if (context.flushSubnormalsToZero()) {
- currentFenv_.__control |= (1U << 24); // control register
+ currentFenv.__control |= (1U << 24); // control register
} else {
- currentFenv_.__control &= ~(1U << 24); // control register
+ currentFenv.__control &= ~(1U << 24); // control register
}
#else
// If F18 is built with other C libraries on AArch64, software flushing will
@@ -70,11 +76,15 @@ void HostFloatingPointEnvironment::SetUpHostFloatingPointEnvironment(
hardwareFlagsAreReliable_ = false;
#endif
errno = 0;
- if (fesetenv(¤tFenv_) != 0) {
+ if (fesetenv(¤tFenv) != 0) {
common::die("Folding with host runtime: fesetenv() failed: %s",
llvm::sys::StrError(errno).c_str());
return;
}
+#if __x86_64__
+ _mm_setcsr(currentMxcsr);
+#endif
+
switch (context.rounding().mode) {
case common::RoundingMode::TiesToEven:
fesetround(FE_TONEAREST);
@@ -141,6 +151,10 @@ void HostFloatingPointEnvironment::CheckAndRestoreFloatingPointEnvironment(
"Folding with host runtime: fesetenv() failed while restoring fenv: %s",
llvm::sys::StrError(errno).c_str());
}
+#if __x86_64__
+ _mm_setcsr(originalMxcsr);
+#endif
+
errno = 0;
}
} // namespace Fortran::evaluate::host
diff --git a/flang/lib/Evaluate/host.h b/flang/lib/Evaluate/host.h
index 20355ae3147a..2fac0424f17c 100644
--- a/flang/lib/Evaluate/host.h
+++ b/flang/lib/Evaluate/host.h
@@ -41,7 +41,9 @@ class HostFloatingPointEnvironment {
private:
std::fenv_t originalFenv_;
- std::fenv_t currentFenv_;
+#if __x86_64__
+ unsigned int originalMxcsr;
+#endif
RealFlags flags_;
bool hasSubnormalFlushingHardwareControl_{false};
bool hardwareFlagsAreReliable_{true};
diff --git a/flang/unittests/Evaluate/fp-testing.cpp b/flang/unittests/Evaluate/fp-testing.cpp
index 66ab7b274a82..94d8d5086d00 100644
--- a/flang/unittests/Evaluate/fp-testing.cpp
+++ b/flang/unittests/Evaluate/fp-testing.cpp
@@ -3,6 +3,9 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
+#if __x86_64__
+#include <xmmintrin.h>
+#endif
using Fortran::common::RoundingMode;
using Fortran::evaluate::RealFlag;
@@ -20,31 +23,38 @@ ScopedHostFloatingPointEnvironment::ScopedHostFloatingPointEnvironment(
llvm::sys::StrError(errno).c_str());
std::abort();
}
- if (fegetenv(¤tFenv_) != 0) {
+ fenv_t currentFenv;
+ if (fegetenv(¤tFenv) != 0) {
std::fprintf(
stderr, "fegetenv() failed: %s\n", llvm::sys::StrError(errno).c_str());
std::abort();
}
+
#if __x86_64__
+ originalMxcsr = _mm_getcsr();
+ unsigned int currentMxcsr{originalMxcsr};
if (treatSubnormalOperandsAsZero) {
- currentFenv_.__mxcsr |= 0x0040;
+ currentMxcsr |= 0x0040;
} else {
- currentFenv_.__mxcsr &= ~0x0040;
+ currentMxcsr &= ~0x0040;
}
if (flushSubnormalResultsToZero) {
- currentFenv_.__mxcsr |= 0x8000;
+ currentMxcsr |= 0x8000;
} else {
- currentFenv_.__mxcsr &= ~0x8000;
+ currentMxcsr &= ~0x8000;
}
#else
// TODO others
#endif
errno = 0;
- if (fesetenv(¤tFenv_) != 0) {
+ if (fesetenv(¤tFenv) != 0) {
std::fprintf(
stderr, "fesetenv() failed: %s\n", llvm::sys::StrError(errno).c_str());
std::abort();
}
+#if __x86_64__
+ _mm_setcsr(currentMxcsr);
+#endif
}
ScopedHostFloatingPointEnvironment::~ScopedHostFloatingPointEnvironment() {
@@ -54,6 +64,9 @@ ScopedHostFloatingPointEnvironment::~ScopedHostFloatingPointEnvironment() {
stderr, "fesetenv() failed: %s\n", llvm::sys::StrError(errno).c_str());
std::abort();
}
+#if __x86_64__
+ _mm_setcsr(originalMxcsr);
+#endif
}
void ScopedHostFloatingPointEnvironment::ClearFlags() const {
diff --git a/flang/unittests/Evaluate/fp-testing.h b/flang/unittests/Evaluate/fp-testing.h
index 760e976c4c96..ee06765879b3 100644
--- a/flang/unittests/Evaluate/fp-testing.h
+++ b/flang/unittests/Evaluate/fp-testing.h
@@ -19,7 +19,9 @@ class ScopedHostFloatingPointEnvironment {
private:
fenv_t originalFenv_;
- fenv_t currentFenv_;
+#if __x86_64__
+ unsigned int originalMxcsr;
+#endif
};
#endif // FORTRAN_TEST_EVALUATE_FP_TESTING_H_
More information about the flang-commits
mailing list