diff options
-rw-r--r-- | clang/include/clang/Driver/ToolChain.h | 7 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChain.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 3 | ||||
-rw-r--r-- | clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtfastmath.o | 0 | ||||
-rw-r--r-- | clang/test/Driver/linux-ld.c | 21 |
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 |