Skip to content

Commit 63ecd2a

Browse files
Disable FTZ/DAZ when compiling shared libraries by default. (#80475)
This fixes #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. This also partially reverts fa7cd54 in that it disables the attempt to set the IR denormal-fp-math attribute based on whether or not -ffast-math is applied as it is insufficiently reliable.
1 parent eb05a2e commit 63ecd2a

File tree

8 files changed

+64
-39
lines changed

8 files changed

+64
-39
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,16 @@ Non-comprehensive list of changes in this release
207207
- ``__typeof_unqual__`` is available in all C modes as an extension, which behaves
208208
like ``typeof_unqual`` from C23, similar to ``__typeof__`` and ``typeof``.
209209

210+
211+
* Shared libraries linked with either the ``-ffast-math``, ``-Ofast``, or
212+
``-funsafe-math-optimizations`` flags will no longer enable flush-to-zero
213+
floating-point mode by default. This decision can be overridden with use of
214+
``-mdaz-ftz``. This behavior now matches GCC's behavior.
215+
(`#57589 <https://github.com/llvm/llvm-project/issues/57589>`_)
216+
217+
* ``-fdenormal-fp-math=preserve-sign`` is no longer implied by ``-ffast-math``
218+
on x86 systems.
219+
210220
New Compiler Flags
211221
------------------
212222
- ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and

clang/docs/UsersManual.rst

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,7 +1506,8 @@ floating point semantic models: precise (the default), strict, and fast.
15061506

15071507
* ``-ffp-contract=fast``
15081508

1509-
Note: ``-ffast-math`` causes ``crtfastmath.o`` to be linked with code. See
1509+
Note: ``-ffast-math`` causes ``crtfastmath.o`` to be linked with code unless
1510+
``-shared`` or ``-mno-daz-ftz`` is present. See
15101511
:ref:`crtfastmath.o` for more details.
15111512

15121513
.. option:: -fno-fast-math
@@ -1560,7 +1561,8 @@ floating point semantic models: precise (the default), strict, and fast.
15601561
``-ffp-contract``.
15611562

15621563
Note: ``-fno-fast-math`` implies ``-fdenormal-fp-math=ieee``.
1563-
``-fno-fast-math`` causes ``crtfastmath.o`` to not be linked with code.
1564+
``-fno-fast-math`` causes ``crtfastmath.o`` to not be linked with code
1565+
unless ``-mdaz-ftz`` is present.
15641566

15651567
.. option:: -fdenormal-fp-math=<value>
15661568

@@ -1938,10 +1940,13 @@ by using ``#pragma STDC FENV_ROUND`` with a value other than ``FE_DYNAMIC``.
19381940

19391941
A note about ``crtfastmath.o``
19401942
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1941-
``-ffast-math`` and ``-funsafe-math-optimizations`` cause ``crtfastmath.o`` to be
1942-
automatically linked, which adds a static constructor that sets the FTZ/DAZ
1943+
``-ffast-math`` and ``-funsafe-math-optimizations`` without the ``-shared``
1944+
option cause ``crtfastmath.o`` to be
1945+
automatically linked, which adds a static constructor that sets the FTZ/DAZ
19431946
bits in MXCSR, affecting not only the current compilation unit but all static
1944-
and shared libraries included in the program.
1947+
and shared libraries included in the program. This decision can be overridden
1948+
by using either the flag ``-mdaz-ftz`` or ``-mno-daz-ftz`` to respectively
1949+
link or not link ``crtfastmath.o``.
19451950

19461951
.. _FLT_EVAL_METHOD:
19471952

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2615,6 +2615,11 @@ defm protect_parens : BoolFOption<"protect-parens",
26152615
"floating-point expressions are evaluated">,
26162616
NegFlag<SetFalse>>;
26172617

2618+
defm daz_ftz : SimpleMFlag<"daz-ftz",
2619+
"Globally set", "Do not globally set",
2620+
" the denormals-are-zero (DAZ) and flush-to-zero (FTZ) bits in the "
2621+
"floating-point control register on program startup">;
2622+
26182623
def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>;
26192624
def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>;
26202625

clang/lib/Driver/ToolChain.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,9 +1307,14 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args,
13071307

13081308
bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args,
13091309
std::string &Path) const {
1310+
// Don't implicitly link in mode-changing libraries in a shared library, since
1311+
// this can have very deleterious effects. See the various links from
1312+
// https://github.com/llvm/llvm-project/issues/57589 for more information.
1313+
bool Default = !Args.hasArgNoClaim(options::OPT_shared);
1314+
13101315
// Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
13111316
// (to keep the linker options consistent with gcc and clang itself).
1312-
if (!isOptimizationLevelFast(Args)) {
1317+
if (Default && !isOptimizationLevelFast(Args)) {
13131318
// Check if -ffast-math or -funsafe-math.
13141319
Arg *A =
13151320
Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
@@ -1318,8 +1323,14 @@ bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args,
13181323

13191324
if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
13201325
A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
1321-
return false;
1326+
Default = false;
13221327
}
1328+
1329+
// Whatever decision came as a result of the above implicit settings, either
1330+
// -mdaz-ftz or -mno-daz-ftz is capable of overriding it.
1331+
if (!Args.hasFlag(options::OPT_mdaz_ftz, options::OPT_mno_daz_ftz, Default))
1332+
return false;
1333+
13231334
// If crtfastmath.o exists add it to the arguments.
13241335
Path = GetFilePath("crtfastmath.o");
13251336
return (Path != "crtfastmath.o"); // Not found.

clang/lib/Driver/ToolChains/Linux.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -842,25 +842,6 @@ void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args,
842842
ToolChain::addProfileRTLibs(Args, CmdArgs);
843843
}
844844

845-
llvm::DenormalMode
846-
Linux::getDefaultDenormalModeForType(const llvm::opt::ArgList &DriverArgs,
847-
const JobAction &JA,
848-
const llvm::fltSemantics *FPType) const {
849-
switch (getTriple().getArch()) {
850-
case llvm::Triple::x86:
851-
case llvm::Triple::x86_64: {
852-
std::string Unused;
853-
// DAZ and FTZ are turned on in crtfastmath.o
854-
if (!DriverArgs.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
855-
isFastMathRuntimeAvailable(DriverArgs, Unused))
856-
return llvm::DenormalMode::getPreserveSign();
857-
return llvm::DenormalMode::getIEEE();
858-
}
859-
default:
860-
return llvm::DenormalMode::getIEEE();
861-
}
862-
}
863-
864845
void Linux::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {
865846
for (const auto &Opt : ExtraOpts)
866847
CmdArgs.push_back(Opt.c_str());

clang/lib/Driver/ToolChains/Linux.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,6 @@ class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
5959

6060
std::vector<std::string> ExtraOpts;
6161

62-
llvm::DenormalMode getDefaultDenormalModeForType(
63-
const llvm::opt::ArgList &DriverArgs, const JobAction &JA,
64-
const llvm::fltSemantics *FPType = nullptr) const override;
65-
6662
const char *getDefaultLinker() const override;
6763

6864
protected:

clang/test/Driver/default-denormal-fp-math.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,6 @@
33

44
// 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
55

6-
// crtfastmath enables ftz and daz
7-
// 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
8-
9-
// crt not linked in with nostartfiles
10-
// 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
11-
12-
// If there's no crtfastmath, don't assume ftz/daz
13-
// RUN: %clang -### -target x86_64-unknown-linux-gnu -ffast-math --sysroot=/dev/null -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-IEEE %s
14-
156
// RUN: %clang -### -target x86_64-scei-ps4 -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-PRESERVESIGN %s
167

178
// Flag omitted for default

clang/test/Driver/linux-ld.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,32 @@
14461446
// RUN: %clang --target=i386-unknown-linux -no-pie -### %s -ffast-math \
14471447
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
14481448
// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
1449+
// Don't link crtfastmath.o with -shared
1450+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -shared \
1451+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1452+
// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
1453+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -Ofast -shared \
1454+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1455+
// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
1456+
// Check for effects of -mdaz-ftz
1457+
// RUN: %clang --target=x86_64-unknown-linux -### %s -ffast-math -shared -mdaz-ftz \
1458+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1459+
// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
1460+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -mdaz-ftz \
1461+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1462+
// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
1463+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -mdaz-ftz \
1464+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1465+
// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
1466+
// RUN: %clang --target=x86_64-unknown-linux -### %s -ffast-math -shared -mno-daz-ftz \
1467+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1468+
// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
1469+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -mno-daz-ftz \
1470+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1471+
// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
1472+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -mno-daz-ftz \
1473+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1474+
// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
14491475
// CHECK-CRTFASTMATH: usr/lib/gcc/x86_64-unknown-linux/10.2.0{{/|\\\\}}crtfastmath.o
14501476
// CHECK-NOCRTFASTMATH-NOT: crtfastmath.o
14511477

0 commit comments

Comments
 (0)