summaryrefslogtreecommitdiff
path: root/lib/Analysis
diff options
context:
space:
mode:
authorAlp Toker <alp@nuanti.com>2014-06-09 18:28:53 +0000
committerAlp Toker <alp@nuanti.com>2014-06-09 18:28:53 +0000
commitf4cf404837d962c67501ee0e07028801c9b10b6d (patch)
tree0bbc516fd88d7cb75dcb07eab6776e5a72f43a4d /lib/Analysis
parent7ffad46ea7edc8a6fa6fd7555c08387faacb8594 (diff)
downloadllvm-f4cf404837d962c67501ee0e07028801c9b10b6d.tar.gz
llvm-f4cf404837d962c67501ee0e07028801c9b10b6d.tar.bz2
llvm-f4cf404837d962c67501ee0e07028801c9b10b6d.tar.xz
Fold FEnv.h into the implementation
Support headers shouldn't use config.h definitions, and they should never be undefined like this. ConstantFolding.cpp was the only user of this facility and already includes config.h for other math features, so it makes sense to move the checks there at point of use. (The implicit config.h was also quite dangerous -- removing the FEnv.h include would have silently disabled math constant folding without causing any tests to fail. Need to investigate -Wundef once the cleanup is done.) This eliminates the last config.h include from LLVM headers, paving the way for more consistent configuration checks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210483 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/ConstantFolding.cpp48
1 files changed, 41 insertions, 7 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index f1294dea97..0b6f11ad82 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -21,6 +21,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
@@ -31,11 +32,22 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Operator.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FEnv.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include <cerrno>
#include <cmath>
+
+#ifdef HAVE_FENV_H
+#include <fenv.h>
+#define USE_FENV
+#endif
+
+// FIXME: Clang's #include handling apparently doesn't work for libstdc++'s
+// fenv.h; see PR6907 for details.
+#if defined(__clang__) && defined(_GLIBCXX_FENV_H)
+#undef USE_FENV
+#endif
+
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -1314,12 +1326,34 @@ static Constant *GetConstantFoldFPValue(double V, Type *Ty) {
}
+namespace {
+/// llvm_fenv_clearexcept - Clear the floating-point exception state.
+static inline void llvm_fenv_clearexcept() {
+#if defined(USE_FENV) && HAVE_DECL_FE_ALL_EXCEPT
+ feclearexcept(FE_ALL_EXCEPT);
+#endif
+ errno = 0;
+}
+
+/// llvm_fenv_testexcept - Test if a floating-point exception was raised.
+static inline bool llvm_fenv_testexcept() {
+ int errno_val = errno;
+ if (errno_val == ERANGE || errno_val == EDOM)
+ return true;
+#if defined(USE_FENV) && HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT
+ if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
+ return true;
+#endif
+ return false;
+}
+} // End namespace
+
static Constant *ConstantFoldFP(double (*NativeFP)(double), double V,
Type *Ty) {
- sys::llvm_fenv_clearexcept();
+ llvm_fenv_clearexcept();
V = NativeFP(V);
- if (sys::llvm_fenv_testexcept()) {
- sys::llvm_fenv_clearexcept();
+ if (llvm_fenv_testexcept()) {
+ llvm_fenv_clearexcept();
return nullptr;
}
@@ -1328,10 +1362,10 @@ static Constant *ConstantFoldFP(double (*NativeFP)(double), double V,
static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),
double V, double W, Type *Ty) {
- sys::llvm_fenv_clearexcept();
+ llvm_fenv_clearexcept();
V = NativeFP(V, W);
- if (sys::llvm_fenv_testexcept()) {
- sys::llvm_fenv_clearexcept();
+ if (llvm_fenv_testexcept()) {
+ llvm_fenv_clearexcept();
return nullptr;
}