Skip to content

Commit 14e683e

Browse files
Disable FTZ/DAZ when compiling shared libraries by default.
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.
1 parent d4de4c3 commit 14e683e

File tree

5 files changed

+67
-7
lines changed

5 files changed

+67
-7
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ C23 Feature Support
117117
Non-comprehensive list of changes in this release
118118
-------------------------------------------------
119119

120+
* Code compiled with ``-shared`` and ``-ffast-math`` will no longer enable
121+
flush-to-zero floating-point mode by default. This decision can be overridden
122+
with use of ``-mdaz-ftz``. This behavior now matches GCC's behavior.
123+
(`#57589 <https://github.com/llvm/llvm-project/issues/57589>`_)
124+
120125
New Compiler Flags
121126
------------------
122127

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

@@ -1907,10 +1909,13 @@ by using ``#pragma STDC FENV_ROUND`` with a value other than ``FE_DYNAMIC``.
19071909

19081910
A note about ``crtfastmath.o``
19091911
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1910-
``-ffast-math`` and ``-funsafe-math-optimizations`` cause ``crtfastmath.o`` to be
1911-
automatically linked, which adds a static constructor that sets the FTZ/DAZ
1912+
``-ffast-math`` and ``-funsafe-math-optimizations`` without the ``-shared``
1913+
option cause ``crtfastmath.o`` to be
1914+
automatically linked, which adds a static constructor that sets the FTZ/DAZ
19121915
bits in MXCSR, affecting not only the current compilation unit but all static
1913-
and shared libraries included in the program.
1916+
and shared libraries included in the program. This decision can be overridden
1917+
by using either the flag ``-mdaz-ftz`` or ``-mno-daz-ftz`` to respectively
1918+
link or not link ``crtfastmath.o``.
19141919

19151920
.. _FLT_EVAL_METHOD:
19161921

clang/include/clang/Driver/Options.td

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

2557+
defm daz_ftz : SimpleMFlag<"daz-ftz",
2558+
"Globally set", "Do not globally set",
2559+
" the denormals-are-zero (DAZ) and flush-to-zero (FTZ) bits in the "
2560+
"floating-point control register on program startup.">;
2561+
25572562
def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>;
25582563
def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>;
25592564

clang/lib/Driver/ToolChain.cpp

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

12721272
bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args,
12731273
std::string &Path) const {
1274+
// Don't implicitly link in mode-changing libraries in a shared library, since
1275+
// this can have very deleterious effects. See the various links from
1276+
// https://github.com/llvm/llvm-project/issues/57589 for more information.
1277+
bool Default = !Args.hasArg(options::OPT_shared);
1278+
12741279
// Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
12751280
// (to keep the linker options consistent with gcc and clang itself).
1276-
if (!isOptimizationLevelFast(Args)) {
1281+
if (Default && !isOptimizationLevelFast(Args)) {
12771282
// Check if -ffast-math or -funsafe-math.
12781283
Arg *A =
12791284
Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
@@ -1282,8 +1287,14 @@ bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args,
12821287

12831288
if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
12841289
A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
1285-
return false;
1290+
Default = false;
12861291
}
1292+
1293+
// Whatever decision came as a result of the above implicit settings, either
1294+
// -mdaz-ftz or -mno-daz-ftz is capable of overriding it.
1295+
if (!Args.hasFlag(options::OPT_mdaz_ftz, options::OPT_mno_daz_ftz, Default))
1296+
return false;
1297+
12871298
// If crtfastmath.o exists add it to the arguments.
12881299
Path = GetFilePath("crtfastmath.o");
12891300
return (Path != "crtfastmath.o"); // Not found.

clang/test/Driver/linux-ld.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,40 @@
15691569
// RUN: --gcc-toolchain="" \
15701570
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
15711571
// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
1572+
// Don't link crtfastmath.o with -shared
1573+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -shared \
1574+
// RUN: --gcc-toolchain="" \
1575+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1576+
// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
1577+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -Ofast -shared \
1578+
// RUN: --gcc-toolchain="" \
1579+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1580+
// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
1581+
// Check for effects of -mdaz-ftz
1582+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -shared -mdaz-ftz \
1583+
// RUN: --gcc-toolchain="" \
1584+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1585+
// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
1586+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -mdaz-ftz \
1587+
// RUN: --gcc-toolchain="" \
1588+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1589+
// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
1590+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -mdaz-ftz \
1591+
// RUN: --gcc-toolchain="" \
1592+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1593+
// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
1594+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -shared -mno-daz-ftz \
1595+
// RUN: --gcc-toolchain="" \
1596+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1597+
// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
1598+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -mno-daz-ftz \
1599+
// RUN: --gcc-toolchain="" \
1600+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1601+
// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
1602+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -mno-daz-ftz \
1603+
// RUN: --gcc-toolchain="" \
1604+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1605+
// RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
15721606
// CHECK-CRTFASTMATH: usr/lib/gcc/x86_64-unknown-linux/10.2.0{{/|\\\\}}crtfastmath.o
15731607
// CHECK-NOCRTFASTMATH-NOT: crtfastmath.o
15741608

0 commit comments

Comments
 (0)