]> granicus.if.org Git - clang/commitdiff
Driver: Link crtfastmath.o if it's available and -ffast-math is specified.
authorBenjamin Kramer <benny.kra@googlemail.com>
Thu, 4 Oct 2012 19:42:20 +0000 (19:42 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Thu, 4 Oct 2012 19:42:20 +0000 (19:42 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165240 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/ToolChain.h
lib/Driver/ToolChain.cpp
lib/Driver/Tools.cpp
test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtfastmath.o [new file with mode: 0644]
test/Driver/linux-ld.c

index 3295e720066cdb71eb60245f36ecf020f401120f..d694e0f27df77648684e485276321949e5ae236e 100644 (file)
@@ -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
index 6bcea58b9eb98eb03b34f1ca69df4887d4f7745c..16c5ae6d9ddd7e552e03664bff8fee911e73f945 100644 (file)
@@ -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;
+}
index 86781cc178e9d93e9edf5165e42a4644b87e5450..9f068b9d7c796b37c95066142e1fd5676c7fffad 100644 (file)
@@ -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/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtfastmath.o b/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtfastmath.o
new file mode 100644 (file)
index 0000000..e69de29
index 7c7837f666cd0ee4b1fadfd501cd1d5630f02b33..7021f92f46b0e1f06d485b2e51c4c6b65fafdab1 100644 (file)
 // 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