Skip to content

Commit 8ba880b

Browse files
author
Andy Kaylor
authored
[Driver] Clean up denormal handling with fast-math-related options (#89477)
This change cleans up the clang driver handling of umbrella options like -ffast-math, -funsafe-math-optimizations, and -ffp-model, and aligns the behavior of -ffp-model=fast with -ffast-math with regard to the linking of crtfastmath.o. We agreed in a previous review that the fast-math options should not attempt to change the -fdenormal-fp-math option, which is inherently target-specific. The clang user's manual claims that -ffp-model=fast "behaves identically to specifying both -ffast-math and -ffp-contract=fast." Since -ffast-math causes crtfastmath.o to be linked if it is available, that should also happen with -ffp-model=fast. I am going to be proposing further changes to -ffp-model=fast, decoupling it from -ffast-math and introducing a new -ffp-model=aggressive that matches the current behavior, but I wanted to solidfy the current behavior before I do that.
1 parent e5907c8 commit 8ba880b

File tree

6 files changed

+30
-28
lines changed

6 files changed

+30
-28
lines changed

clang/docs/UsersManual.rst

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,8 +1452,6 @@ floating point semantic models: precise (the default), strict, and fast.
14521452
"fenv_access", "off", "on", "off"
14531453
"rounding_mode", "tonearest", "dynamic", "tonearest"
14541454
"contract", "on", "off", "fast"
1455-
"denormal_fp_math", "IEEE", "IEEE", "IEEE"
1456-
"denormal_fp32_math", "IEEE","IEEE", "IEEE"
14571455
"support_math_errno", "on", "on", "off"
14581456
"no_honor_nans", "off", "off", "on"
14591457
"no_honor_infinities", "off", "off", "on"
@@ -1462,6 +1460,14 @@ floating point semantic models: precise (the default), strict, and fast.
14621460
"allow_approximate_fns", "off", "off", "on"
14631461
"allow_reassociation", "off", "off", "on"
14641462

1463+
The ``-ffp-model`` option does not modify the ``fdenormal-fp-math``
1464+
setting, but it does have an impact on whether ``crtfastmath.o`` is
1465+
linked. Because linking ``crtfastmath.o`` has a global effect on the
1466+
program, and because the global denormal handling can be changed in
1467+
other ways, the state of ``fdenormal-fp-math`` handling cannot
1468+
be assumed in any function based on fp-model. See :ref:`crtfastmath.o`
1469+
for more details.
1470+
14651471
.. option:: -ffast-math
14661472

14671473
Enable fast-math mode. This option lets the
@@ -1537,7 +1543,6 @@ floating point semantic models: precise (the default), strict, and fast.
15371543
Also, this option resets following options to their target-dependent defaults.
15381544

15391545
* ``-f[no-]math-errno``
1540-
* ``-fdenormal-fp-math=<value>``
15411546

15421547
There is ambiguity about how ``-ffp-contract``, ``-ffast-math``,
15431548
and ``-fno-fast-math`` behave when combined. To keep the value of
@@ -1560,8 +1565,7 @@ floating point semantic models: precise (the default), strict, and fast.
15601565
``-ffp-contract`` setting is determined by the default value of
15611566
``-ffp-contract``.
15621567

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

15671571
.. option:: -fdenormal-fp-math=<value>
@@ -1694,7 +1698,6 @@ floating point semantic models: precise (the default), strict, and fast.
16941698
* ``-fsigned-zeros``
16951699
* ``-ftrapping-math``
16961700
* ``-ffp-contract=on``
1697-
* ``-fdenormal-fp-math=ieee``
16981701

16991702
There is ambiguity about how ``-ffp-contract``,
17001703
``-funsafe-math-optimizations``, and ``-fno-unsafe-math-optimizations``

clang/lib/Driver/ToolChain.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,14 +1316,19 @@ bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args,
13161316
// (to keep the linker options consistent with gcc and clang itself).
13171317
if (Default && !isOptimizationLevelFast(Args)) {
13181318
// Check if -ffast-math or -funsafe-math.
1319-
Arg *A =
1320-
Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
1321-
options::OPT_funsafe_math_optimizations,
1322-
options::OPT_fno_unsafe_math_optimizations);
1319+
Arg *A = Args.getLastArg(
1320+
options::OPT_ffast_math, options::OPT_fno_fast_math,
1321+
options::OPT_funsafe_math_optimizations,
1322+
options::OPT_fno_unsafe_math_optimizations, options::OPT_ffp_model_EQ);
13231323

13241324
if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
13251325
A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
13261326
Default = false;
1327+
if (A && A->getOption().getID() == options::OPT_ffp_model_EQ) {
1328+
StringRef Model = A->getValue();
1329+
if (Model != "fast")
1330+
Default = false;
1331+
}
13271332
}
13281333

13291334
// Whatever decision came as a result of the above implicit settings, either

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,13 +2743,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
27432743
StringRef FPExceptionBehavior = "";
27442744
// -ffp-eval-method options: double, extended, source
27452745
StringRef FPEvalMethod = "";
2746-
const llvm::DenormalMode DefaultDenormalFPMath =
2746+
llvm::DenormalMode DenormalFPMath =
27472747
TC.getDefaultDenormalModeForType(Args, JA);
2748-
const llvm::DenormalMode DefaultDenormalFP32Math =
2748+
llvm::DenormalMode DenormalFP32Math =
27492749
TC.getDefaultDenormalModeForType(Args, JA, &llvm::APFloat::IEEEsingle());
27502750

2751-
llvm::DenormalMode DenormalFPMath = DefaultDenormalFPMath;
2752-
llvm::DenormalMode DenormalFP32Math = DefaultDenormalFP32Math;
27532751
// CUDA and HIP don't rely on the frontend to pass an ffp-contract option.
27542752
// If one wasn't given by the user, don't pass it here.
27552753
StringRef FPContract;
@@ -2899,11 +2897,6 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
28992897
SignedZeros = true;
29002898
// -fno_fast_math restores default denormal and fpcontract handling
29012899
FPContract = "on";
2902-
DenormalFPMath = llvm::DenormalMode::getIEEE();
2903-
2904-
// FIXME: The target may have picked a non-IEEE default mode here based on
2905-
// -cl-denorms-are-zero. Should the target consider -fp-model interaction?
2906-
DenormalFP32Math = llvm::DenormalMode::getIEEE();
29072900

29082901
StringRef Val = A->getValue();
29092902
if (OFastEnabled && !Val.equals("fast")) {
@@ -3122,9 +3115,6 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
31223115
TrappingMath = true;
31233116
FPExceptionBehavior = "strict";
31243117

3125-
// The target may have opted to flush by default, so force IEEE.
3126-
DenormalFPMath = llvm::DenormalMode::getIEEE();
3127-
DenormalFP32Math = llvm::DenormalMode::getIEEE();
31283118
if (!JA.isDeviceOffloading(Action::OFK_Cuda) &&
31293119
!JA.isOffloading(Action::OFK_HIP)) {
31303120
if (LastSeenFfpContractOption != "") {
@@ -3154,9 +3144,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
31543144
ReciprocalMath = false;
31553145
ApproxFunc = false;
31563146
SignedZeros = true;
3157-
// -fno_fast_math restores default denormal and fpcontract handling
3158-
DenormalFPMath = DefaultDenormalFPMath;
3159-
DenormalFP32Math = llvm::DenormalMode::getIEEE();
3147+
// -fno_fast_math restores default fpcontract handling
31603148
if (!JA.isDeviceOffloading(Action::OFK_Cuda) &&
31613149
!JA.isOffloading(Action::OFK_HIP)) {
31623150
if (LastSeenFfpContractOption != "") {
@@ -3171,8 +3159,6 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
31713159
// subsequent options conflict then emit warning diagnostic.
31723160
if (HonorINFs && HonorNaNs && !AssociativeMath && !ReciprocalMath &&
31733161
SignedZeros && TrappingMath && RoundingFPMath && !ApproxFunc &&
3174-
DenormalFPMath == llvm::DenormalMode::getIEEE() &&
3175-
DenormalFP32Math == llvm::DenormalMode::getIEEE() &&
31763162
FPContract.equals("off"))
31773163
// OK: Current Arg doesn't conflict with -ffp-model=strict
31783164
;

clang/test/Driver/fp-model.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@
6464

6565
// RUN: %clang -### -ffp-model=strict -fdenormal-fp-math=preserve-sign,preserve-sign -c %s 2>&1 \
6666
// RUN: | FileCheck --check-prefix=WARN10 %s
67-
// WARN10: warning: overriding '-ffp-model=strict' option with '-fdenormal-fp-math=preserve-sign,preserve-sign' [-Woverriding-option]
67+
// WARN10: "-cc1"
68+
// WARN10-NOT: warning: overriding '-ffp-model=strict' option with '-fdenormal-fp-math=preserve-sign,preserve-sign' [-Woverriding-option]
6869

6970
// RUN: %clang -### -ffp-model=fast -ffp-model=strict -c %s 2>&1 | FileCheck \
7071
// RUN: --check-prefix=WARN11 %s
@@ -128,6 +129,7 @@
128129
// RUN: | FileCheck --check-prefix=CHECK-NO-EXCEPT %s
129130
// RUN: %clang -### -nostdinc -ffp-model=strict -Ofast -c %s 2>&1 \
130131
// RUN: | FileCheck --check-prefix=CHECK-NO-EXCEPT %s
132+
// CHECK-NO-EXCEPT: "-cc1"
131133
// CHECK-NO-EXCEPT-NOT: "-ffp-exception-behavior=strict"
132134

133135
// RUN: %clang -### -nostdinc -ffp-exception-behavior=strict -c %s 2>&1 \

clang/test/Driver/linux-ld.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,9 @@
14061406
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -funsafe-math-optimizations\
14071407
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
14081408
// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
1409+
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffp-model=fast \
1410+
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
1411+
// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
14091412
// RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -Ofast\
14101413
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
14111414
// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s

clang/test/Driver/solaris-ld.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@
193193
// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -ffast-math \
194194
// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
195195
// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH-SPARC32 %s
196+
// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -ffp-model=fast \
197+
// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
198+
// RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH-SPARC32 %s
196199
// CHECK-CRTFASTMATH-SPARC32: "-isysroot" "[[SYSROOT:[^"]+]]"
197200
// CHECK-CRTFASTMATH-SPARC32: "[[SYSROOT]]/usr/gcc/4.8/lib/gcc/sparc-sun-solaris2.11/4.8.2{{/|\\\\}}crtfastmath.o"
198201
// CHECK-NOCRTFASTMATH-SPARC32-NOT: crtfastmath.o

0 commit comments

Comments
 (0)