From d53585be8fab3180a82b9bc7f4c40a5162e08eeb Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Tue, 25 Mar 2014 18:02:07 +0000 Subject: [PATCH] Fix an logic error in the clang driver preventing crtfastmath.o from linking when -Ofast is used without -ffast-math In gcc using -Ofast forces linking of crtfastmath.o. In the current clang crtfastmath.o is only linked when -ffast-math/-funsafe-math-optimizations passed. It can lead to performance issues, when using only -Ofast without explicit -ffast-math (I faced with it). My patch fixes inconsistency with gcc behaviour and also introduces few tests on it. Patch by Zinovy Nis! Differential Revision: http://llvm-reviews.chandlerc.com/D3114 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204742 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/Driver.h | 4 ++++ include/clang/Driver/ToolChain.h | 2 +- lib/Driver/Driver.cpp | 4 ++++ lib/Driver/ToolChain.cpp | 23 +++++++++++++---------- lib/Driver/Tools.cpp | 7 ------- test/Driver/linux-ld.c | 23 ++++++++++++++++++++++- 6 files changed, 44 insertions(+), 19 deletions(-) diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 056c28549a..044872591f 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -415,6 +415,10 @@ public: bool &HadExtra); }; +/// \return True if the last defined optimization level is -Ofast. +/// And False otherwise. +bool isOptimizationLevelFast(const llvm::opt::ArgList &Args); + } // end namespace driver } // end namespace clang diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index 9c7f4b52c1..a43ee10751 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -311,7 +311,7 @@ public: /// 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. + /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags. virtual bool AddFastMathRuntimeIfAvailable(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index c318b60a93..5cc19f5f8e 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -2049,3 +2049,7 @@ std::pair Driver::getIncludeExcludeOptionFlagMasks() const { return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask); } + +bool clang::driver::isOptimizationLevelFast(const llvm::opt::ArgList &Args) { + return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group, false); +} diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index 4103914d29..9f756f7c63 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -341,16 +341,19 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args, 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; - + // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed + // (to keep the linker options consistent with gcc and clang itself). + if (!isOptimizationLevelFast(Args)) { + // Check if -ffast-math or -funsafe-math. + 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. diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index ef3e00329d..c90fb81f03 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -2034,13 +2034,6 @@ static void SplitDebugInfo(const ToolChain &TC, Compilation &C, C.addCommand(new Command(JA, T, Exec, StripArgs)); } -static bool isOptimizationLevelFast(const ArgList &Args) { - if (Arg *A = Args.getLastArg(options::OPT_O_Group)) - if (A->getOption().matches(options::OPT_Ofast)) - return true; - return false; -} - /// \brief Vectorize at all optimization levels greater than 1 except for -Oz. static bool shouldEnableVectorizerAtOLevel(const ArgList &Args) { if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c index 2d1f8ed08c..ca390d9b3b 100644 --- a/test/Driver/linux-ld.c +++ b/test/Driver/linux-ld.c @@ -825,7 +825,7 @@ // 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. +// Check that crtfastmath.o is linked with -ffast-math and with -Ofast. // RUN: %clang --target=x86_64-unknown-linux -### %s \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s @@ -835,9 +835,30 @@ // 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 -Ofast\ +// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s +// RUN: %clang --target=x86_64-unknown-linux -### %s -Ofast -O3\ +// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s +// RUN: %clang --target=x86_64-unknown-linux -### %s -O3 -Ofast\ +// 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 +// RUN: %clang --target=x86_64-unknown-linux -### %s -Ofast -fno-fast-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 -Ofast -fno-unsafe-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 -fno-fast-math -Ofast \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s +// RUN: %clang --target=x86_64-unknown-linux -### %s -fno-unsafe-math-optimizations -Ofast \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %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 \ -- 2.40.0