summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/TargetLibraryInfo.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2013-12-28 02:40:19 +0000
committerChandler Carruth <chandlerc@gmail.com>2013-12-28 02:40:19 +0000
commitf5689f830414bdb60ce56ff37c182b6cebcedd0b (patch)
tree49f7fe7665dfd24df1ecaaffabbf606e9dda1481 /llvm/lib/Target/TargetLibraryInfo.cpp
parent8458862f20c6f4baf40d90edda6886a87a9bd3bb (diff)
downloadbcm5719-llvm-f5689f830414bdb60ce56ff37c182b6cebcedd0b.tar.gz
bcm5719-llvm-f5689f830414bdb60ce56ff37c182b6cebcedd0b.zip
Disable transforms that introduce calls to exp10*() on Linux due to
widespread glibc bugs. The glibc implementation of exp10 has a very serious precision bug in version 2.15 (and older versions). This is still very widely used (the current Ubuntu LTS for example uses it) and so it isn't reasonable to make transforms that produce these functions. This fixes many miscompiles introduced when we started transforming pow(10.0, ...) into exp10, and it may have fixed other latent miscompiles where exp10 provided sufficient precision but exp10f did not. This is all really horrible. The primary bug has been fixed for over a year and glibc 2.18 works correctly for the test cases I have, but it will be 2017 before the LTS using 2.15 is no longer supported by Ubuntu (and thus reasonable for folks to be relying on). =[ We're either going to need to live without these optimizations, or find a way to switch behavior more dynamically than using simply the fact that the OS is "Linux". To make matters worse, there appears to be significant testing and fixing of numerous other bugs in the exp10 family of functions right now in glibc. While those haven't been causing problems I've seen in the wild, it gives me concerns that we may need to wait until an even later release of glibc before we can reliably transform code into exp10. llvm-svn: 198093
Diffstat (limited to 'llvm/lib/Target/TargetLibraryInfo.cpp')
-rw-r--r--llvm/lib/Target/TargetLibraryInfo.cpp16
1 files changed, 10 insertions, 6 deletions
diff --git a/llvm/lib/Target/TargetLibraryInfo.cpp b/llvm/lib/Target/TargetLibraryInfo.cpp
index b208bfd3728..93c008af350 100644
--- a/llvm/lib/Target/TargetLibraryInfo.cpp
+++ b/llvm/lib/Target/TargetLibraryInfo.cpp
@@ -574,14 +574,11 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T,
TLI.setUnavailable(LibFunc::llabs);
}
- // exp10, exp10f, exp10l is available on at least Linux (GLIBC)
- // exp10 and exp10f are not available on OS X until 10.9 and iOS until 7.0
- // and their names are __exp10 and __exp10f. exp10l is not available on
- // OS X or iOS.
switch (T.getOS()) {
- case Triple::Linux:
- break;
case Triple::MacOSX:
+ // exp10 and exp10f are not available on OS X until 10.9 and iOS until 7.0
+ // and their names are __exp10 and __exp10f. exp10l is not available on
+ // OS X or iOS.
TLI.setUnavailable(LibFunc::exp10l);
if (T.isMacOSXVersionLT(10, 9)) {
TLI.setUnavailable(LibFunc::exp10);
@@ -601,6 +598,13 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T,
TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f");
}
break;
+ case Triple::Linux:
+ // exp10, exp10f, exp10l is available on Linux (GLIBC) but are extremely
+ // buggy prior to glibc version 2.18. Until this version is widely deployed
+ // or we have a reasonable detection strategy, we cannot use exp10 reliably
+ // on Linux.
+ //
+ // Fall through to disable all of them.
default:
TLI.setUnavailable(LibFunc::exp10);
TLI.setUnavailable(LibFunc::exp10f);
OpenPOWER on IntegriCloud