summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2012-10-04 19:42:20 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2012-10-04 19:42:20 +0000
commit058666a8d02f5cd348150862a3401c9c4bd0b4d0 (patch)
tree528e657ffa85743e93147dcf2632a66d1da5949f
parentfe5e770c6dc7f8b6615b1d40efb18755cd9c5609 (diff)
downloadbcm5719-llvm-058666a8d02f5cd348150862a3401c9c4bd0b4d0.tar.gz
bcm5719-llvm-058666a8d02f5cd348150862a3401c9c4bd0b4d0.zip
Driver: Link crtfastmath.o if it's available and -ffast-math is specified.
crtfastmath.o contains routines to set the floating point flags to a faster, unsafe mode. Linking it in speeds up code dealing with denormals significantly (PR14024). For now this is only enabled on linux where I can test it and crtfastmath.o is widely available. We may want to provide a similar file with compiler-rt eventually and/or enable it on other platforms too. llvm-svn: 165240
-rw-r--r--clang/include/clang/Driver/ToolChain.h7
-rw-r--r--clang/lib/Driver/ToolChain.cpp22
-rw-r--r--clang/lib/Driver/Tools.cpp3
-rw-r--r--clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtfastmath.o0
-rw-r--r--clang/test/Driver/linux-ld.c21
5 files changed, 53 insertions, 0 deletions
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index 3295e720066..d694e0f27df 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -252,6 +252,13 @@ public:
/// for kernel extensions (Darwin-specific).
virtual void AddCCKextLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const;
+
+ /// AddFastMathRuntimeIfAvailable - If a runtime library exists that sets
+ /// global flags for unsafe floating point math, add it and return true.
+ ///
+ /// This checks for presence of the -ffast-math or -funsafe-math flags.
+ virtual bool AddFastMathRuntimeIfAvailable(const ArgList &Args,
+ ArgStringList &CmdArgs) const;
};
} // end namespace driver
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 6bcea58b9eb..16c5ae6d9dd 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -14,6 +14,7 @@
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Option.h"
#include "clang/Driver/Options.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
@@ -281,3 +282,24 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
CmdArgs.push_back("-lcc_kext");
}
+
+bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ // Check if -ffast-math or -funsafe-math is enabled.
+ Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_fno_fast_math,
+ options::OPT_funsafe_math_optimizations,
+ options::OPT_fno_unsafe_math_optimizations);
+
+ if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
+ A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
+ return false;
+
+ // If crtfastmath.o exists add it to the arguments.
+ std::string Path = GetFilePath("crtfastmath.o");
+ if (Path == "crtfastmath.o") // Not found.
+ return false;
+
+ CmdArgs.push_back(Args.MakeArgString(Path));
+ return true;
+}
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 86781cc178e..9f068b9d7c7 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -5828,6 +5828,9 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
else
crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
+
+ // Add crtfastmath.o if available and fast math is enabled.
+ ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
}
Args.AddAllArgs(CmdArgs, options::OPT_L);
diff --git a/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtfastmath.o b/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtfastmath.o
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtfastmath.o
diff --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c
index 7c7837f666c..7021f92f46b 100644
--- a/clang/test/Driver/linux-ld.c
+++ b/clang/test/Driver/linux-ld.c
@@ -501,3 +501,24 @@
// CHECK-FSL-PPC64: "{{.*}}/crt1.o"
// CHECK-FSL-PPC64: "{{.*}}/crtbegin.o"
// CHECK-FSL-PPC64: "-L[[SYSROOT]]/usr/lib64/powerpc64-fsl-linux/4.6.2/../.."
+//
+// Check that crtfastmath.o is linked with -ffast-math.
+// RUN: %clang -target x86_64-unknown-linux -### %s \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
+// RUN: %clang -target x86_64-unknown-linux -### %s -ffast-math \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
+// RUN: %clang -target x86_64-unknown-linux -### %s -funsafe-math-optimizations\
+// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
+// RUN: %clang -target x86_64-unknown-linux -### %s -ffast-math -fno-fast-math \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
+// We don't have crtfastmath.o in the i386 tree, use it to check that file
+// detection works.
+// RUN: %clang -target i386-unknown-linux -### %s -ffast-math \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
+// CHECK-CRTFASTMATH: usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtfastmath.o
+// CHECK-NOCRTFASTMATH-NOT: crtfastmath.o
OpenPOWER on IntegriCloud