Skip to content

Commit 9ee59aa

Browse files
author
Andy Kaylor
committed
[Driver] Introduce ffp-model=aggressive
This change modifies -ffp-model=fast to select options that more closely match -funsafe-math-optimizations, and introduces a new model, -ffp-model=aggressive which matches the existing behavior (except for a minor change in the fp-contract behavior). The primary motivation for this change is to make -ffp-model=fast more user friendly, particularly in light of LLVM's aggressive optimizations when -fno-honor-nans and -fno-honor-infinites are used. This was previously proposed here: https://discourse.llvm.org/t/making-ffp-model-fast-more-user-friendly/78402
1 parent 7022498 commit 9ee59aa

File tree

6 files changed

+93
-49
lines changed

6 files changed

+93
-49
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,16 @@ Modified Compiler Flags
176176

177177
- The compiler flag `-fbracket-depth` default value is increased from 256 to 2048.
178178

179+
- The ``-ffp-model`` option has been updated to enable a more limited set of
180+
optimizations when the ``fast`` argument is used and to accept a new argument,
181+
``aggressive``. The behavior of ``-ffp-model=aggressive`` is mostly equivalent
182+
to the previous behavior of ``-ffp-model=fast``. The updated
183+
``-ffp-model=fast`` behavior no longer assumes finite math only and uses a
184+
the ``promoted`` algorithm for complex division when possible rather than the
185+
less robust Smith algorithm. Both ``-ffp-model=fast`` and
186+
``-ffp-model=aggressive`` will now imply ``-ffp-contract=fast-honor-pragmas``
187+
rather than ``-ffp-contract=fast``.
188+
179189
Removed Compiler Flags
180190
-------------------------
181191

clang/docs/UsersManual.rst

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,28 +1452,30 @@ describes the various floating point semantic modes and the corresponding option
14521452
"fhonor-infinities", "{on, off}"
14531453
"fsigned-zeros", "{on, off}"
14541454
"freciprocal-math", "{on, off}"
1455-
"allow_approximate_fns", "{on, off}"
1455+
"fallow-approximate-fns", "{on, off}"
14561456
"fassociative-math", "{on, off}"
1457+
"fcomplex-arithmetic", "{basic, improved, full, promoted}"
14571458

14581459
This table describes the option settings that correspond to the three
14591460
floating point semantic models: precise (the default), strict, and fast.
14601461

14611462

14621463
.. csv-table:: Floating Point Models
1463-
:header: "Mode", "Precise", "Strict", "Fast"
1464-
:widths: 25, 15, 15, 15
1465-
1466-
"except_behavior", "ignore", "strict", "ignore"
1467-
"fenv_access", "off", "on", "off"
1468-
"rounding_mode", "tonearest", "dynamic", "tonearest"
1469-
"contract", "on", "off", "fast"
1470-
"support_math_errno", "on", "on", "off"
1471-
"no_honor_nans", "off", "off", "on"
1472-
"no_honor_infinities", "off", "off", "on"
1473-
"no_signed_zeros", "off", "off", "on"
1474-
"allow_reciprocal", "off", "off", "on"
1475-
"allow_approximate_fns", "off", "off", "on"
1476-
"allow_reassociation", "off", "off", "on"
1464+
:header: "Mode", "Precise", "Strict", "Fast", "Aggressive"
1465+
:widths: 25, 25, 25, 25, 25
1466+
1467+
"except_behavior", "ignore", "strict", "ignore", "ignore"
1468+
"fenv_access", "off", "on", "off", "off"
1469+
"rounding_mode", "tonearest", "dynamic", "tonearest", "tonearest"
1470+
"contract", "on", "off", "fast-honor-pragmas", "fast-honor-pragmas"
1471+
"support_math_errno", "on", "on", "off", "off"
1472+
"no_honor_nans", "off", "off", "off", "on"
1473+
"no_honor_infinities", "off", "off", "off", "on"
1474+
"no_signed_zeros", "off", "off", "on", "on"
1475+
"allow_reciprocal", "off", "off", "on", "on"
1476+
"allow_approximate_fns", "off", "off", "on", "on"
1477+
"allow_reassociation", "off", "off", "on", "on"
1478+
"complex_arithmetic", "full", "full", "promoted", "basic"
14771479

14781480
The ``-ffp-model`` option does not modify the ``fdenormal-fp-math``
14791481
setting, but it does have an impact on whether ``crtfastmath.o`` is
@@ -1492,9 +1494,9 @@ for more details.
14921494
* Floating-point math obeys regular algebraic rules for real numbers (e.g.
14931495
``+`` and ``*`` are associative, ``x/y == x * (1/y)``, and
14941496
``(a + b) * c == a * c + b * c``),
1495-
* Operands to floating-point operations are not equal to ``NaN`` and
1496-
``Inf``, and
1497-
* ``+0`` and ``-0`` are interchangeable.
1497+
* No ``NaN`` or infinite values will be operands or results of
1498+
floating-point operations,
1499+
* ``+0`` and ``-0`` may be treated as interchangeable.
14981500

14991501
``-ffast-math`` also defines the ``__FAST_MATH__`` preprocessor
15001502
macro. Some math libraries recognize this macro and change their behavior.
@@ -1753,7 +1755,7 @@ for more details.
17531755
Specify floating point behavior. ``-ffp-model`` is an umbrella
17541756
option that encompasses functionality provided by other, single
17551757
purpose, floating point options. Valid values are: ``precise``, ``strict``,
1756-
and ``fast``.
1758+
``fast``, and ``aggressive``.
17571759
Details:
17581760

17591761
* ``precise`` Disables optimizations that are not value-safe on
@@ -1766,7 +1768,10 @@ for more details.
17661768
``STDC FENV_ACCESS``: by default ``FENV_ACCESS`` is disabled. This option
17671769
setting behaves as though ``#pragma STDC FENV_ACCESS ON`` appeared at the
17681770
top of the source file.
1769-
* ``fast`` Behaves identically to specifying both ``-ffast-math`` and
1771+
* ``fast`` Behaves identically to specifying ``-funsafe-math-optimizations``,
1772+
``-fno-math-errno`` and ``-fcomplex-arithmetic=promoted``
1773+
``ffp-contract=fast``
1774+
* ``aggressive`` Behaves identically to specifying both ``-ffast-math`` and
17701775
``ffp-contract=fast``
17711776

17721777
Note: If your command line specifies multiple instances

clang/lib/Driver/ToolChain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1366,7 +1366,7 @@ bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args,
13661366
Default = false;
13671367
if (A && A->getOption().getID() == options::OPT_ffp_model_EQ) {
13681368
StringRef Model = A->getValue();
1369-
if (Model != "fast")
1369+
if (Model != "fast" && Model != "aggressive")
13701370
Default = false;
13711371
}
13721372
}

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2919,9 +2919,19 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
29192919
std::string GccRangeComplexOption = "";
29202920

29212921
// Lambda to set fast-math options. This is also used by -ffp-model=fast
2922-
auto applyFastMath = [&]() {
2923-
HonorINFs = false;
2924-
HonorNaNs = false;
2922+
auto applyFastMath = [&](bool Aggressive) {
2923+
LangOptions::ComplexRangeKind NewRange;
2924+
if (Aggressive) {
2925+
HonorINFs = false;
2926+
HonorNaNs = false;
2927+
FPContract = "fast";
2928+
NewRange = LangOptions::ComplexRangeKind::CX_Basic;
2929+
} else {
2930+
HonorINFs = true;
2931+
HonorNaNs = true;
2932+
FPContract = "fast-honor-pragmas";
2933+
NewRange = LangOptions::ComplexRangeKind::CX_Promoted;
2934+
}
29252935
MathErrno = false;
29262936
AssociativeMath = true;
29272937
ReciprocalMath = true;
@@ -2930,21 +2940,16 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
29302940
TrappingMath = false;
29312941
RoundingFPMath = false;
29322942
FPExceptionBehavior = "";
2933-
// If fast-math is set then set the fp-contract mode to fast.
2934-
FPContract = "fast";
2935-
// ffast-math enables basic range rules for complex multiplication and
2936-
// division.
29372943
// Warn if user expects to perform full implementation of complex
29382944
// multiplication or division in the presence of nan or ninf flags.
2939-
if (Range == LangOptions::ComplexRangeKind::CX_Full ||
2940-
Range == LangOptions::ComplexRangeKind::CX_Improved ||
2941-
Range == LangOptions::ComplexRangeKind::CX_Promoted)
2945+
if (Range != NewRange)
29422946
EmitComplexRangeDiag(
2943-
D, ComplexArithmeticStr(Range),
2947+
D,
29442948
!GccRangeComplexOption.empty()
29452949
? GccRangeComplexOption
2946-
: ComplexArithmeticStr(LangOptions::ComplexRangeKind::CX_Basic));
2947-
Range = LangOptions::ComplexRangeKind::CX_Basic;
2950+
: ComplexArithmeticStr(Range),
2951+
ComplexArithmeticStr(NewRange));
2952+
Range = NewRange;
29482953
SeenUnsafeMathModeOption = true;
29492954
};
29502955

@@ -3072,8 +3077,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
30723077
SignedZeros = true;
30733078

30743079
StringRef Val = A->getValue();
3075-
if (OFastEnabled && Val != "fast") {
3076-
// Only -ffp-model=fast is compatible with OFast, ignore.
3080+
if (OFastEnabled && Val != "aggressive") {
3081+
// Only -ffp-model=aggressive is compatible with OFast, ignore.
30773082
D.Diag(clang::diag::warn_drv_overriding_option)
30783083
<< Args.MakeArgString("-ffp-model=" + Val) << "-Ofast";
30793084
break;
@@ -3085,10 +3090,15 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
30853090
<< Args.MakeArgString("-ffp-model=" + Val);
30863091
if (Val == "fast") {
30873092
FPModel = Val;
3088-
applyFastMath();
3093+
applyFastMath(false);
30893094
// applyFastMath sets fp-contract="fast"
30903095
LastFpContractOverrideOption = "-ffp-model=fast";
3091-
} else if (Val == "precise") {
3096+
} else if (Val.equals("aggressive")) {
3097+
FPModel = Val;
3098+
applyFastMath(true);
3099+
// applyFastMath sets fp-contract="fast"
3100+
LastFpContractOverrideOption = "-ffp-model=aggressive";
3101+
} else if (Val.equals("precise")) {
30923102
FPModel = Val;
30933103
FPContract = "on";
30943104
LastFpContractOverrideOption = "-ffp-model=precise";
@@ -3280,7 +3290,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
32803290
continue;
32813291
[[fallthrough]];
32823292
case options::OPT_ffast_math:
3283-
applyFastMath();
3293+
applyFastMath(true);
32843294
if (A->getOption().getID() == options::OPT_Ofast)
32853295
LastFpContractOverrideOption = "-Ofast";
32863296
else

clang/test/CodeGen/ffp-model.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// RUN: %clang -S -emit-llvm -fenable-matrix -ffp-model=fast %s -o - \
44
// RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-FAST
55

6+
// RUN: %clang -S -emit-llvm -fenable-matrix -ffp-model=aggressive %s -o - \
7+
// RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-AGGRESSIVE
8+
69
// RUN: %clang -S -emit-llvm -fenable-matrix -ffp-model=precise %s -o - \
710
// RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-PRECISE
811

@@ -20,9 +23,13 @@ float mymuladd(float x, float y, float z) {
2023
// CHECK: define{{.*}} float @mymuladd
2124
return x * y + z;
2225

23-
// CHECK-FAST: fmul fast float
26+
// CHECK-AGGRESSIVE: fmul fast float
27+
// CHECK-AGGRESSIVE: load float, ptr
28+
// CHECK-AGGRESSIVE: fadd fast float
29+
30+
// CHECK-FAST: fmul reassoc nsz arcp contract afn float
2431
// CHECK-FAST: load float, ptr
25-
// CHECK-FAST: fadd fast float
32+
// CHECK-FAST: fadd reassoc nsz arcp contract afn float
2633

2734
// CHECK-PRECISE: load float, ptr
2835
// CHECK-PRECISE: load float, ptr
@@ -54,9 +61,13 @@ void my_vec_muladd(v2f x, float y, v2f z, v2f *res) {
5461
// CHECK: define{{.*}}@my_vec_muladd
5562
*res = x * y + z;
5663

57-
// CHECK-FAST: fmul fast <2 x float>
64+
// CHECK-AGGRESSIVE: fmul fast <2 x float>
65+
// CHECK-AGGRESSIVE: load <2 x float>, ptr
66+
// CHECK-AGGRESSIVE: fadd fast <2 x float>
67+
68+
// CHECK-FAST: fmul reassoc nsz arcp contract afn <2 x float>
5869
// CHECK-FAST: load <2 x float>, ptr
59-
// CHECK-FAST: fadd fast <2 x float>
70+
// CHECK-FAST: fadd reassoc nsz arcp contract afn <2 x float>
6071

6172
// CHECK-PRECISE: load <2 x float>, ptr
6273
// CHECK-PRECISE: load float, ptr
@@ -88,9 +99,13 @@ void my_m21_muladd(m21f x, float y, m21f z, m21f *res) {
8899
// CHECK: define{{.*}}@my_m21_muladd
89100
*res = x * y + z;
90101

91-
// CHECK-FAST: fmul fast <2 x float>
102+
// CHECK-AGGRESSIVE: fmul fast <2 x float>
103+
// CHECK-AGGRESSIVE: load <2 x float>, ptr
104+
// CHECK-AGGRESSIVE: fadd fast <2 x float>
105+
106+
// CHECK-FAST: fmul reassoc nsz arcp contract afn <2 x float>
92107
// CHECK-FAST: load <2 x float>, ptr
93-
// CHECK-FAST: fadd fast <2 x float>
108+
// CHECK-FAST: fadd reassoc nsz arcp contract afn <2 x float>
94109

95110
// CHECK-PRECISE: load <2 x float>, ptr
96111
// CHECK-PRECISE: load float, ptr
@@ -122,9 +137,13 @@ void my_m22_muladd(m22f x, float y, m22f z, m22f *res) {
122137
// CHECK: define{{.*}}@my_m22_muladd
123138
*res = x * y + z;
124139

125-
// CHECK-FAST: fmul fast <4 x float>
140+
// CHECK-AGGRESSIVE: fmul fast <4 x float>
141+
// CHECK-AGGRESSIVE: load <4 x float>, ptr
142+
// CHECK-AGGRESSIVE: fadd fast <4 x float>
143+
144+
// CHECK-FAST: fmul reassoc nsz arcp contract afn <4 x float>
126145
// CHECK-FAST: load <4 x float>, ptr
127-
// CHECK-FAST: fadd fast <4 x float>
146+
// CHECK-FAST: fadd reassoc nsz arcp contract afn <4 x float>
128147

129148
// CHECK-PRECISE: load <4 x float>, ptr
130149
// CHECK-PRECISE: load float, ptr

clang/test/Driver/fp-model.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
// and other floating point options get a warning diagnostic.
33
//
44

5-
// RUN: %clang -### -ffp-model=fast -ffp-contract=off -c %s 2>&1 \
5+
// RUN: %clang -### -ffp-model=aggressive -ffp-contract=off -c %s 2>&1 \
66
// RUN: | FileCheck --check-prefix=WARN %s
77
// WARN: warning: overriding '-ffp-model=fast' option with '-ffp-contract=off' [-Woverriding-option]
88

9-
// RUN: %clang -### -ffp-model=fast -ffp-contract=on -c %s 2>&1 \
9+
// RUN: %clang -### -ffp-model=aggressive -ffp-contract=on -c %s 2>&1 \
1010
// RUN: | FileCheck --check-prefix=WARN1 %s
1111
// WARN1: warning: overriding '-ffp-model=fast' option with '-ffp-contract=on' [-Woverriding-option]
1212

0 commit comments

Comments
 (0)