https://github.com/jcranmer-intel updated https://github.com/llvm/llvm-project/pull/80475
>From 971cc613e994a308f939f68247257b65e04c74fa Mon Sep 17 00:00:00 2001 From: Joshua Cranmer <joshua.cran...@intel.com> Date: Fri, 2 Feb 2024 10:35:29 -0800 Subject: [PATCH 1/3] Disable FTZ/DAZ when compiling shared libraries by default. This fixes https://github.com/llvm/llvm-project/issues/57589, and aligns Clang with the behavior of current versions of gcc. There is a new option, -mdaz-ftz, to control the linking of the file that sets FTZ/DAZ on startup, and this flag is on by default if -ffast-math is present and -shared isn't. --- clang/docs/ReleaseNotes.rst | 6 +++++ clang/docs/UsersManual.rst | 15 ++++++++---- clang/include/clang/Driver/Options.td | 5 ++++ clang/lib/Driver/ToolChain.cpp | 15 ++++++++++-- clang/test/Driver/linux-ld.c | 34 +++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 7 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d1f7293a842bb6..8fd41d07c57262 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -207,6 +207,12 @@ Non-comprehensive list of changes in this release - ``__typeof_unqual__`` is available in all C modes as an extension, which behaves like ``typeof_unqual`` from C23, similar to ``__typeof__`` and ``typeof``. + +* Code compiled with ``-shared`` and ``-ffast-math`` will no longer enable + flush-to-zero floating-point mode by default. This decision can be overridden + with use of ``-mdaz-ftz``. This behavior now matches GCC's behavior. + (`#57589 <https://github.com/llvm/llvm-project/issues/57589>`_) + New Compiler Flags ------------------ - ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 8df40566fcba3d..d0326f01d251e0 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1506,7 +1506,8 @@ floating point semantic models: precise (the default), strict, and fast. * ``-ffp-contract=fast`` - Note: ``-ffast-math`` causes ``crtfastmath.o`` to be linked with code. See + Note: ``-ffast-math`` causes ``crtfastmath.o`` to be linked with code unless + ``-shared`` or ``-mno-daz-ftz`` is present. See :ref:`crtfastmath.o` for more details. .. option:: -fno-fast-math @@ -1560,7 +1561,8 @@ floating point semantic models: precise (the default), strict, and fast. ``-ffp-contract``. Note: ``-fno-fast-math`` implies ``-fdenormal-fp-math=ieee``. - ``-fno-fast-math`` causes ``crtfastmath.o`` to not be linked with code. + ``-fno-fast-math`` causes ``crtfastmath.o`` to not be linked with code + unless ``-mdaz-ftz`` is present. .. option:: -fdenormal-fp-math=<value> @@ -1938,10 +1940,13 @@ by using ``#pragma STDC FENV_ROUND`` with a value other than ``FE_DYNAMIC``. A note about ``crtfastmath.o`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -``-ffast-math`` and ``-funsafe-math-optimizations`` cause ``crtfastmath.o`` to be -automatically linked, which adds a static constructor that sets the FTZ/DAZ +``-ffast-math`` and ``-funsafe-math-optimizations`` without the ``-shared`` +option cause ``crtfastmath.o`` to be +automatically linked, which adds a static constructor that sets the FTZ/DAZ bits in MXCSR, affecting not only the current compilation unit but all static -and shared libraries included in the program. +and shared libraries included in the program. This decision can be overridden +by using either the flag ``-mdaz-ftz`` or ``-mno-daz-ftz`` to respectively +link or not link ``crtfastmath.o``. .. _FLT_EVAL_METHOD: diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 922bda721dc780..f59b6962daf261 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2615,6 +2615,11 @@ defm protect_parens : BoolFOption<"protect-parens", "floating-point expressions are evaluated">, NegFlag<SetFalse>>; +defm daz_ftz : SimpleMFlag<"daz-ftz", + "Globally set", "Do not globally set", + " the denormals-are-zero (DAZ) and flush-to-zero (FTZ) bits in the " + "floating-point control register on program startup.">; + def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>; def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>; diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 237092ed07e5dc..a3979e91589e88 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1307,9 +1307,14 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args, bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, std::string &Path) const { + // Don't implicitly link in mode-changing libraries in a shared library, since + // this can have very deleterious effects. See the various links from + // https://github.com/llvm/llvm-project/issues/57589 for more information. + bool Default = !Args.hasArg(options::OPT_shared); + // 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)) { + if (Default && !isOptimizationLevelFast(Args)) { // Check if -ffast-math or -funsafe-math. Arg *A = Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math, @@ -1318,8 +1323,14 @@ bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, if (!A || A->getOption().getID() == options::OPT_fno_fast_math || A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations) - return false; + Default = false; } + + // Whatever decision came as a result of the above implicit settings, either + // -mdaz-ftz or -mno-daz-ftz is capable of overriding it. + if (!Args.hasFlag(options::OPT_mdaz_ftz, options::OPT_mno_daz_ftz, Default)) + return false; + // If crtfastmath.o exists add it to the arguments. Path = GetFilePath("crtfastmath.o"); return (Path != "crtfastmath.o"); // Not found. diff --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c index d918f4f2d7dbd9..41b1717f070f55 100644 --- a/clang/test/Driver/linux-ld.c +++ b/clang/test/Driver/linux-ld.c @@ -1446,6 +1446,40 @@ // RUN: %clang --target=i386-unknown-linux -no-pie -### %s -ffast-math \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s +// Don't link crtfastmath.o with -shared +// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -shared \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s +// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -Ofast -shared \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s +// Check for effects of -mdaz-ftz +// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -shared -mdaz-ftz \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s +// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -mdaz-ftz \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s +// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -mdaz-ftz \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s +// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -shared -mno-daz-ftz \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s +// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -mno-daz-ftz \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s +// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -mno-daz-ftz \ +// RUN: --gcc-toolchain="" \ +// 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/10.2.0{{/|\\\\}}crtfastmath.o // CHECK-NOCRTFASTMATH-NOT: crtfastmath.o >From d96c5ee6d5e4807434685570702653b4c670bbb8 Mon Sep 17 00:00:00 2001 From: Joshua Cranmer <joshua.cran...@intel.com> Date: Fri, 2 Feb 2024 11:01:04 -0800 Subject: [PATCH 2/3] Address review comments. --- clang/docs/ReleaseNotes.rst | 7 ++++--- clang/include/clang/Driver/Options.td | 2 +- clang/test/Driver/linux-ld.c | 12 ++---------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8fd41d07c57262..0a1649dca7b993 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -208,9 +208,10 @@ Non-comprehensive list of changes in this release like ``typeof_unqual`` from C23, similar to ``__typeof__`` and ``typeof``. -* Code compiled with ``-shared`` and ``-ffast-math`` will no longer enable - flush-to-zero floating-point mode by default. This decision can be overridden - with use of ``-mdaz-ftz``. This behavior now matches GCC's behavior. +* Shared libraries linked with either the ``-ffast-math``, ``-Ofast``, or + ``-funsafe-math-optimizations`` flags will no longer enable flush-to-zero + floating-point mode by default. This decision can be overridden with use of + ``-mdaz-ftz``. This behavior now matches GCC's behavior. (`#57589 <https://github.com/llvm/llvm-project/issues/57589>`_) New Compiler Flags diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index f59b6962daf261..4cb0b840df87b1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2618,7 +2618,7 @@ defm protect_parens : BoolFOption<"protect-parens", defm daz_ftz : SimpleMFlag<"daz-ftz", "Globally set", "Do not globally set", " the denormals-are-zero (DAZ) and flush-to-zero (FTZ) bits in the " - "floating-point control register on program startup.">; + "floating-point control register on program startup">; def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>; def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>; diff --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c index 41b1717f070f55..958e682b6c3c11 100644 --- a/clang/test/Driver/linux-ld.c +++ b/clang/test/Driver/linux-ld.c @@ -1448,36 +1448,28 @@ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s // Don't link crtfastmath.o with -shared // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -shared \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -Ofast -shared \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s // Check for effects of -mdaz-ftz -// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -shared -mdaz-ftz \ -// RUN: --gcc-toolchain="" \ +// RUN: %clang --target=x86_64-unknown-linux -### %s -ffast-math -shared -mdaz-ftz \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -mdaz-ftz \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -mdaz-ftz \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s -// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -shared -mno-daz-ftz \ -// RUN: --gcc-toolchain="" \ +// RUN: %clang --target=x86_64-unknown-linux -### %s -ffast-math -shared -mno-daz-ftz \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -mno-daz-ftz \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -mno-daz-ftz \ -// RUN: --gcc-toolchain="" \ // 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/10.2.0{{/|\\\\}}crtfastmath.o >From 5b9cd163ff1e88ae83d5566dbb7c0395fee91725 Mon Sep 17 00:00:00 2001 From: Joshua Cranmer <joshua.cran...@intel.com> Date: Thu, 22 Feb 2024 10:28:15 -0800 Subject: [PATCH 3/3] Partially revert fa7cd549d60. The guessing of whether or not FTZ/DAZ mode would be enabled is insufficiently accurate. --- clang/lib/Driver/ToolChains/Linux.cpp | 19 ------------------- clang/lib/Driver/ToolChains/Linux.h | 4 ---- clang/test/Driver/default-denormal-fp-math.c | 9 --------- 3 files changed, 32 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index fb65881061effc..db2c20d7b461d0 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -842,25 +842,6 @@ void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args, ToolChain::addProfileRTLibs(Args, CmdArgs); } -llvm::DenormalMode -Linux::getDefaultDenormalModeForType(const llvm::opt::ArgList &DriverArgs, - const JobAction &JA, - const llvm::fltSemantics *FPType) const { - switch (getTriple().getArch()) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: { - std::string Unused; - // DAZ and FTZ are turned on in crtfastmath.o - if (!DriverArgs.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) && - isFastMathRuntimeAvailable(DriverArgs, Unused)) - return llvm::DenormalMode::getPreserveSign(); - return llvm::DenormalMode::getIEEE(); - } - default: - return llvm::DenormalMode::getIEEE(); - } -} - void Linux::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { for (const auto &Opt : ExtraOpts) CmdArgs.push_back(Opt.c_str()); diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h index 524391743090ba..2d9e674e50a630 100644 --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -59,10 +59,6 @@ class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF { std::vector<std::string> ExtraOpts; - llvm::DenormalMode getDefaultDenormalModeForType( - const llvm::opt::ArgList &DriverArgs, const JobAction &JA, - const llvm::fltSemantics *FPType = nullptr) const override; - const char *getDefaultLinker() const override; protected: diff --git a/clang/test/Driver/default-denormal-fp-math.c b/clang/test/Driver/default-denormal-fp-math.c index 5f87e151df49e4..c04ad5c08b8d0d 100644 --- a/clang/test/Driver/default-denormal-fp-math.c +++ b/clang/test/Driver/default-denormal-fp-math.c @@ -3,15 +3,6 @@ // RUN: %clang -### -target x86_64-unknown-linux-gnu --sysroot=%S/Inputs/basic_linux_tree -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-IEEE %s -// crtfastmath enables ftz and daz -// RUN: %clang -### -target x86_64-unknown-linux-gnu -ffast-math --sysroot=%S/Inputs/basic_linux_tree -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-PRESERVESIGN %s - -// crt not linked in with nostartfiles -// RUN: %clang -### -target x86_64-unknown-linux-gnu -ffast-math -nostartfiles --sysroot=%S/Inputs/basic_linux_tree -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-IEEE %s - -// If there's no crtfastmath, don't assume ftz/daz -// RUN: %clang -### -target x86_64-unknown-linux-gnu -ffast-math --sysroot=/dev/null -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-IEEE %s - // RUN: %clang -### -target x86_64-scei-ps4 -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-PRESERVESIGN %s // Flag omitted for default _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits