Skip to content

Commit af57dbf

Browse files
author
Melanie Blower
committed
Add support for options -frounding-math, ftrapping-math, -ffp-model=, and -ffp-exception-behavior=
Add options to control floating point behavior: trapping and exception behavior, rounding, and control of optimizations that affect floating point calculations. More details in UsersManual.rst. Reviewers: rjmccall Differential Revision: https://reviews.llvm.org/D62731
1 parent de61aa3 commit af57dbf

File tree

13 files changed

+540
-19
lines changed

13 files changed

+540
-19
lines changed

clang/docs/UsersManual.rst

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,10 +1231,10 @@ are listed below.
12311231

12321232
**-f[no-]trapping-math**
12331233

1234-
``-fno-trapping-math`` allows optimizations that assume that
1235-
floating point operations cannot generate traps such as divide-by-zero,
1236-
overflow and underflow. Defaults to ``-ftrapping-math``.
1237-
Currently this option has no effect.
1234+
Control floating point exception behavior. ``-fno-trapping-math`` allows optimizations that assume that floating point operations cannot generate traps such as divide-by-zero, overflow and underflow.
1235+
1236+
- The option ``-ftrapping-math`` behaves identically to ``-ffp-exception-behavior=strict``.
1237+
- The option ``-fno-trapping-math`` behaves identically to ``-ffp-exception-behavior=ignore``. This is the default.
12381238

12391239
.. option:: -ffp-contract=<value>
12401240

@@ -1319,6 +1319,52 @@ are listed below.
13191319

13201320
Defaults to ``-fno-finite-math``.
13211321

1322+
.. _opt_frounding-math:
1323+
1324+
**-f[no-]rounding-math**
1325+
1326+
Force floating-point operations to honor the dynamically-set rounding mode by default.
1327+
1328+
The result of a floating-point operation often cannot be exactly represented in the result type and therefore must be rounded. IEEE 754 describes different rounding modes that control how to perform this rounding, not all of which are supported by all implementations. C provides interfaces (``fesetround`` and ``fesetenv``) for dynamically controlling the rounding mode, and while it also recommends certain conventions for changing the rounding mode, these conventions are not typically enforced in the ABI. Since the rounding mode changes the numerical result of operations, the compiler must understand something about it in order to optimize floating point operations.
1329+
1330+
Note that floating-point operations performed as part of constant initialization are formally performed prior to the start of the program and are therefore not subject to the current rounding mode. This includes the initialization of global variables and local ``static`` variables. Floating-point operations in these contexts will be rounded using ``FE_TONEAREST``.
1331+
1332+
- The option ``-fno-rounding-math`` allows the compiler to assume that the rounding mode is set to ``FE_TONEAREST``. This is the default.
1333+
- The option ``-frounding-math`` forces the compiler to honor the dynamically-set rounding mode. This prevents optimizations which might affect results if the rounding mode changes or is different from the default; for example, it prevents floating-point operations from being reordered across most calls and prevents constant-folding when the result is not exactly representable.
1334+
1335+
.. option:: -ffp-model=<value>
1336+
1337+
Specify floating point behavior. ``-ffp-model`` is an umbrella
1338+
option that encompasses functionality provided by other, single
1339+
purpose, floating point options. Valid values are: ``precise``, ``strict``,
1340+
and ``fast``.
1341+
Details:
1342+
1343+
* ``precise`` Disables optimizations that are not value-safe on floating-point data, although FP contraction (FMA) is enabled (``-ffp-contract=fast``). This is the default behavior.
1344+
* ``strict`` Enables ``-frounding-math`` and ``-ffp-exception-behavior=strict``, and disables contractions (FMA). All of the ``-ffast-math`` enablements are disabled.
1345+
* ``fast`` Behaves identically to specifying both ``-ffast-math`` and ``ffp-contract=fast``
1346+
1347+
Note: If your command line specifies multiple instances
1348+
of the ``-ffp-model`` option, or if your command line option specifies
1349+
``-ffp-model`` and later on the command line selects a floating point
1350+
option that has the effect of negating part of the ``ffp-model`` that
1351+
has been selected, then the compiler will issue a diagnostic warning
1352+
that the override has occurred.
1353+
1354+
.. option:: -ffp-exception-behavior=<value>
1355+
1356+
Specify the floating-point exception behavior.
1357+
1358+
Valid values are: ``ignore``, ``maytrap``, and ``strict``.
1359+
The default value is ``ignore``. Details:
1360+
1361+
* ``ignore`` The compiler assumes that the exception status flags will not be read and that floating point exceptions will be masked.
1362+
* ``maytrap`` The compiler avoids transformations that may raise exceptions that would not have been raised by the original code. Constant folding performed by the compiler is exempt from this option.
1363+
* ``strict`` The compiler ensures that all transformations strictly preserve the floating point exception semantics of the original code.
1364+
1365+
1366+
1367+
13221368
.. _controlling-code-generation:
13231369

13241370
Controlling Code Generation

clang/include/clang/Basic/LangOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating poi
254254
LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
255255
/// FP_CONTRACT mode (on/off/fast).
256256
ENUM_LANGOPT(DefaultFPContractMode, FPContractModeKind, 2, FPC_Off, "FP contraction type")
257+
ENUM_LANGOPT(FPRoundingMode, FPRoundingModeKind, 3, FPR_ToNearest, "FP Rounding Mode type")
258+
ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type")
257259
LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
258260
LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
259261
LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")

clang/include/clang/Basic/LangOptions.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,34 @@ class LangOptions : public LangOptionsBase {
184184
FEA_On
185185
};
186186

187+
// Values of the following enumerations correspond to metadata arguments
188+
// specified for constrained floating-point intrinsics:
189+
// http://llvm.org/docs/LangRef.html#constrained-floating-point-intrinsics.
190+
191+
/// Possible rounding modes.
192+
enum FPRoundingModeKind {
193+
/// Rounding to nearest, corresponds to "round.tonearest".
194+
FPR_ToNearest,
195+
/// Rounding toward -Inf, corresponds to "round.downward".
196+
FPR_Downward,
197+
/// Rounding toward +Inf, corresponds to "round.upward".
198+
FPR_Upward,
199+
/// Rounding toward zero, corresponds to "round.towardzero".
200+
FPR_TowardZero,
201+
/// Is determined by runtime environment, corresponds to "round.dynamic".
202+
FPR_Dynamic
203+
};
204+
205+
/// Possible floating point exception behavior.
206+
enum FPExceptionModeKind {
207+
/// Assume that floating-point exceptions are masked.
208+
FPE_Ignore,
209+
/// Transformations do not cause new exceptions but may hide some.
210+
FPE_MayTrap,
211+
/// Strictly preserve the floating-point exception semantics.
212+
FPE_Strict
213+
};
214+
187215
enum class LaxVectorConversionKind {
188216
/// Permit no implicit vector bitcasts.
189217
None,

clang/include/clang/Driver/Options.td

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,10 @@ def : Flag<["-"], "fextended-identifiers">, Group<clang_ignored_f_Group>;
928928
def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>, Flags<[Unsupported]>;
929929
def fhosted : Flag<["-"], "fhosted">, Group<f_Group>;
930930
def fdenormal_fp_math_EQ : Joined<["-"], "fdenormal-fp-math=">, Group<f_Group>, Flags<[CC1Option]>;
931+
def ffp_model_EQ : Joined<["-"], "ffp-model=">, Group<f_Group>, Flags<[DriverOption]>,
932+
HelpText<"Controls the semantics of floating-point calculations.">;
933+
def ffp_exception_behavior_EQ : Joined<["-"], "ffp-exception-behavior=">, Group<f_Group>, Flags<[CC1Option]>,
934+
HelpText<"Specifies the exception behavior of floating-point operations.">;
931935
def ffast_math : Flag<["-"], "ffast-math">, Group<f_Group>, Flags<[CC1Option]>,
932936
HelpText<"Allow aggressive, lossy floating-point optimizations">;
933937
def fno_fast_math : Flag<["-"], "fno-fast-math">, Group<f_Group>;
@@ -1150,6 +1154,8 @@ def fno_honor_infinities : Flag<["-"], "fno-honor-infinities">, Group<f_Group>;
11501154
// This option was originally misspelt "infinites" [sic].
11511155
def : Flag<["-"], "fhonor-infinites">, Alias<fhonor_infinities>;
11521156
def : Flag<["-"], "fno-honor-infinites">, Alias<fno_honor_infinities>;
1157+
def frounding_math : Flag<["-"], "frounding-math">, Group<f_Group>, Flags<[CC1Option]>;
1158+
def fno_rounding_math : Flag<["-"], "fno-rounding-math">, Group<f_Group>, Flags<[CC1Option]>;
11531159
def ftrapping_math : Flag<["-"], "ftrapping-math">, Group<f_Group>, Flags<[CC1Option]>;
11541160
def fno_trapping_math : Flag<["-"], "fno-trapping-math">, Group<f_Group>, Flags<[CC1Option]>;
11551161
def ffp_contract : Joined<["-"], "ffp-contract=">, Group<f_Group>,
@@ -3228,7 +3234,6 @@ defm profile_values : BooleanFFlag<"profile-values">, Group<clang_ignored_gcc_op
32283234
defm regs_graph : BooleanFFlag<"regs-graph">, Group<clang_ignored_f_Group>;
32293235
defm rename_registers : BooleanFFlag<"rename-registers">, Group<clang_ignored_gcc_optimization_f_Group>;
32303236
defm ripa : BooleanFFlag<"ripa">, Group<clang_ignored_f_Group>;
3231-
defm rounding_math : BooleanFFlag<"rounding-math">, Group<clang_ignored_gcc_optimization_f_Group>;
32323237
defm schedule_insns : BooleanFFlag<"schedule-insns">, Group<clang_ignored_gcc_optimization_f_Group>;
32333238
defm schedule_insns2 : BooleanFFlag<"schedule-insns2">, Group<clang_ignored_gcc_optimization_f_Group>;
32343239
defm see : BooleanFFlag<"see">, Group<clang_ignored_f_Group>;

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "clang/Frontend/FrontendDiagnostic.h"
3434
#include "llvm/IR/DataLayout.h"
3535
#include "llvm/IR/Dominators.h"
36+
#include "llvm/IR/IntrinsicInst.h"
3637
#include "llvm/IR/Intrinsics.h"
3738
#include "llvm/IR/MDBuilder.h"
3839
#include "llvm/IR/Operator.h"
@@ -87,6 +88,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
8788
FMF.setAllowReassoc();
8889
}
8990
Builder.setFastMathFlags(FMF);
91+
SetFPModel();
9092
}
9193

9294
CodeGenFunction::~CodeGenFunction() {
@@ -102,6 +104,59 @@ CodeGenFunction::~CodeGenFunction() {
102104
CGM.getOpenMPRuntime().functionFinished(*this);
103105
}
104106

107+
// Map the LangOption for rounding mode into
108+
// the corresponding enum in the IR.
109+
static llvm::ConstrainedFPIntrinsic::RoundingMode ToConstrainedRoundingMD(
110+
LangOptions::FPRoundingModeKind Kind) {
111+
112+
switch (Kind) {
113+
case LangOptions::FPR_ToNearest:
114+
return llvm::ConstrainedFPIntrinsic::rmToNearest;
115+
case LangOptions::FPR_Downward:
116+
return llvm::ConstrainedFPIntrinsic::rmDownward;
117+
case LangOptions::FPR_Upward:
118+
return llvm::ConstrainedFPIntrinsic::rmUpward;
119+
case LangOptions::FPR_TowardZero:
120+
return llvm::ConstrainedFPIntrinsic::rmTowardZero;
121+
case LangOptions::FPR_Dynamic:
122+
return llvm::ConstrainedFPIntrinsic::rmDynamic;
123+
}
124+
llvm_unreachable("Unsupported FP RoundingMode");
125+
}
126+
127+
// Map the LangOption for exception behavior into
128+
// the corresponding enum in the IR.
129+
static llvm::ConstrainedFPIntrinsic::ExceptionBehavior ToConstrainedExceptMD(
130+
LangOptions::FPExceptionModeKind Kind) {
131+
132+
switch (Kind) {
133+
case LangOptions::FPE_Ignore:
134+
return llvm::ConstrainedFPIntrinsic::ebIgnore;
135+
case LangOptions::FPE_MayTrap:
136+
return llvm::ConstrainedFPIntrinsic::ebMayTrap;
137+
case LangOptions::FPE_Strict:
138+
return llvm::ConstrainedFPIntrinsic::ebStrict;
139+
}
140+
llvm_unreachable("Unsupported FP Exception Behavior");
141+
}
142+
143+
void CodeGenFunction::SetFPModel() {
144+
auto fpRoundingMode = ToConstrainedRoundingMD(
145+
getLangOpts().getFPRoundingMode());
146+
auto fpExceptionBehavior = ToConstrainedExceptMD(
147+
getLangOpts().getFPExceptionMode());
148+
149+
if (fpExceptionBehavior == llvm::ConstrainedFPIntrinsic::ebIgnore &&
150+
fpRoundingMode == llvm::ConstrainedFPIntrinsic::rmToNearest)
151+
// Constrained intrinsics are not used.
152+
;
153+
else {
154+
Builder.setIsFPConstrained(true);
155+
Builder.setDefaultConstrainedRounding(fpRoundingMode);
156+
Builder.setDefaultConstrainedExcept(fpExceptionBehavior);
157+
}
158+
}
159+
105160
CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment(QualType T,
106161
LValueBaseInfo *BaseInfo,
107162
TBAAAccessInfo *TBAAInfo) {

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4156,6 +4156,9 @@ class CodeGenFunction : public CodeGenTypeCache {
41564156
/// point operation, expressed as the maximum relative error in ulp.
41574157
void SetFPAccuracy(llvm::Value *Val, float Accuracy);
41584158

4159+
/// SetFPModel - Control floating point behavior via fp-model settings.
4160+
void SetFPModel();
4161+
41594162
private:
41604163
llvm::MDNode *getRangeForLoadFromType(QualType Ty);
41614164
void EmitReturnOfRValue(RValue RV, QualType Ty);

0 commit comments

Comments
 (0)