[FPEnv] Use single enum to represent rounding mode
Now compiler defines 5 sets of constants to represent rounding mode.
These are:
1. `llvm::APFloatBase::roundingMode`. It specifies all 5 rounding modes
defined by IEEE-754 and is used in `APFloat` implementation.
2. `clang::LangOptions::FPRoundingModeKind`. It specifies 4 of 5 IEEE-754
rounding modes and a special value for dynamic rounding mode. It is used
in clang frontend.
3. `llvm::fp::RoundingMode`. Defines the same values as
`clang::LangOptions::FPRoundingModeKind` but in different order. It is
used to specify rounding mode in in IR and functions that operate IR.
4. Rounding mode representation used by `FLT_ROUNDS` (C11, 5.2.4.2.2p7).
Besides constants for rounding mode it also uses a special value to
indicate error. It is convenient to use in intrinsic functions, as it
represents platform-independent representation for rounding mode. In this
role it is used in some pending patches.
5. Values like `FE_DOWNWARD` and other, which specify rounding mode in
library calls `fesetround` and `fegetround`. Often they represent bits
of some control register, so they are target-dependent. The same names
(not values) and a special name `FE_DYNAMIC` are used in
`#pragma STDC FENV_ROUND`.
The first 4 sets of constants are target independent and could have the
same numerical representation. It would simplify conversion between the
representations. Also now `clang::LangOptions::FPRoundingModeKind` and
`llvm::fp::RoundingMode` do not contain the value for IEEE-754 rounding
direction `roundTiesToAway`, although it is supported natively on
some targets.
This change defines all the rounding mode type via one `llvm::RoundingMode`,
which also contains rounding mode for IEEE rounding direction `roundTiesToAway`.
Differential Revision: https://reviews.llvm.org/D77379
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 51dc87b..bddd0f0 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -263,7 +263,7 @@
LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
/// FP_CONTRACT mode (on/off/fast).
ENUM_LANGOPT(DefaultFPContractMode, FPContractModeKind, 2, FPC_Off, "FP contraction type")
-ENUM_LANGOPT(FPRoundingMode, FPRoundingModeKind, 3, FPR_ToNearest, "FP Rounding Mode type")
+ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3, RoundingMode::NearestTiesToEven, "FP Rounding Mode type")
ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type")
LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 0a0cbaf..95b435b 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -19,6 +19,7 @@
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/Visibility.h"
+#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include <string>
@@ -53,6 +54,7 @@
class LangOptions : public LangOptionsBase {
public:
using Visibility = clang::Visibility;
+ using RoundingMode = llvm::RoundingMode;
enum GCMode { NonGC, GCOnly, HybridGC };
enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
@@ -190,23 +192,9 @@
FEA_On
};
- // Values of the following enumerations correspond to metadata arguments
- // specified for constrained floating-point intrinsics:
- // http://llvm.org/docs/LangRef.html#constrained-floating-point-intrinsics.
-
- /// Possible rounding modes.
- enum FPRoundingModeKind {
- /// Rounding to nearest, corresponds to "round.tonearest".
- FPR_ToNearest,
- /// Rounding toward -Inf, corresponds to "round.downward".
- FPR_Downward,
- /// Rounding toward +Inf, corresponds to "round.upward".
- FPR_Upward,
- /// Rounding toward zero, corresponds to "round.towardzero".
- FPR_TowardZero,
- /// Is determined by runtime environment, corresponds to "round.dynamic".
- FPR_Dynamic
- };
+ /// Alias for RoundingMode::NearestTiesToEven.
+ static constexpr unsigned FPR_ToNearest =
+ static_cast<unsigned>(llvm::RoundingMode::NearestTiesToEven);
/// Possible floating point exception behavior.
enum FPExceptionModeKind {
@@ -386,6 +374,8 @@
/// Floating point control options
class FPOptions {
+ using RoundingMode = llvm::RoundingMode;
+
public:
FPOptions() : fp_contract(LangOptions::FPC_Off),
fenv_access(LangOptions::FEA_Off),
@@ -395,10 +385,10 @@
// Used for serializing.
explicit FPOptions(unsigned I)
- : fp_contract(static_cast<LangOptions::FPContractModeKind>(I & 3)),
- fenv_access(static_cast<LangOptions::FEnvAccessModeKind>((I >> 2) & 1)),
- rounding(static_cast<LangOptions::FPRoundingModeKind>((I >> 3) & 7)),
- exceptions(static_cast<LangOptions::FPExceptionModeKind>((I >> 6) & 3))
+ : fp_contract(I & 3),
+ fenv_access((I >> 2) & 1),
+ rounding ((I >> 3) & 7),
+ exceptions ((I >> 6) & 3)
{}
explicit FPOptions(const LangOptions &LangOpts)
@@ -437,12 +427,12 @@
void setDisallowFEnvAccess() { fenv_access = LangOptions::FEA_Off; }
- LangOptions::FPRoundingModeKind getRoundingMode() const {
- return static_cast<LangOptions::FPRoundingModeKind>(rounding);
+ RoundingMode getRoundingMode() const {
+ return static_cast<RoundingMode>(rounding);
}
- void setRoundingMode(LangOptions::FPRoundingModeKind RM) {
- rounding = RM;
+ void setRoundingMode(RoundingMode RM) {
+ rounding = static_cast<unsigned>(RM);
}
LangOptions::FPExceptionModeKind getExceptionMode() const {
@@ -454,7 +444,7 @@
}
bool isFPConstrained() const {
- return getRoundingMode() != LangOptions::FPR_ToNearest ||
+ return getRoundingMode() != RoundingMode::NearestTiesToEven ||
getExceptionMode() != LangOptions::FPE_Ignore ||
allowFEnvAccess();
}
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4645ef8..f2b0a95 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9592,7 +9592,7 @@
void ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC);
/// Called to set rounding mode for floating point operations.
- void setRoundingMode(LangOptions::FPRoundingModeKind);
+ void setRoundingMode(llvm::RoundingMode);
/// Called to set exception behavior for floating point operations.
void setExceptionMode(LangOptions::FPExceptionModeKind);
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index b01a5a4..05bf70e 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -115,21 +115,6 @@
OMPBuilder->finalize();
}
-// Map the LangOption for rounding mode into
-// the corresponding enum in the IR.
-static llvm::fp::RoundingMode ToConstrainedRoundingMD(
- LangOptions::FPRoundingModeKind Kind) {
-
- switch (Kind) {
- case LangOptions::FPR_ToNearest: return llvm::fp::rmToNearest;
- case LangOptions::FPR_Downward: return llvm::fp::rmDownward;
- case LangOptions::FPR_Upward: return llvm::fp::rmUpward;
- case LangOptions::FPR_TowardZero: return llvm::fp::rmTowardZero;
- case LangOptions::FPR_Dynamic: return llvm::fp::rmDynamic;
- }
- llvm_unreachable("Unsupported FP RoundingMode");
-}
-
// Map the LangOption for exception behavior into
// the corresponding enum in the IR.
static llvm::fp::ExceptionBehavior ToConstrainedExceptMD(
@@ -144,18 +129,17 @@
}
void CodeGenFunction::SetFPModel() {
- auto fpRoundingMode = ToConstrainedRoundingMD(
- getLangOpts().getFPRoundingMode());
+ llvm::RoundingMode RM = getLangOpts().getFPRoundingMode();
auto fpExceptionBehavior = ToConstrainedExceptMD(
getLangOpts().getFPExceptionMode());
if (fpExceptionBehavior == llvm::fp::ebIgnore &&
- fpRoundingMode == llvm::fp::rmToNearest)
+ RM == llvm::RoundingMode::NearestTiesToEven)
// Constrained intrinsics are not used.
;
else {
Builder.setIsFPConstrained(true);
- Builder.setDefaultConstrainedRounding(fpRoundingMode);
+ Builder.setDefaultConstrainedRounding(RM);
Builder.setDefaultConstrainedExcept(fpExceptionBehavior);
}
}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 23638e1..cebfb0b 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -47,6 +47,7 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/CachedHashString.h"
+#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
@@ -3188,9 +3189,9 @@
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
}
- LangOptions::FPRoundingModeKind FPRM = LangOptions::FPR_ToNearest;
+ auto FPRM = llvm::RoundingMode::NearestTiesToEven;
if (Args.hasArg(OPT_frounding_math)) {
- FPRM = LangOptions::FPR_Dynamic;
+ FPRM = llvm::RoundingMode::Dynamic;
}
Opts.setFPRoundingMode(FPRM);
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 6a2f744..9141a28 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -940,7 +940,7 @@
}
}
-void Sema::setRoundingMode(LangOptions::FPRoundingModeKind FPR) {
+void Sema::setRoundingMode(llvm::RoundingMode FPR) {
FPFeatures.setRoundingMode(FPR);
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5c6b947..6f7ff37 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -50,6 +50,7 @@
#include "llvm/Support/SaveAndRestore.h"
using namespace clang;
using namespace sema;
+using llvm::RoundingMode;
/// Determine whether the use of this declaration is valid, without
/// emitting diagnostics.
@@ -13639,7 +13640,7 @@
CompLHSTy = UsualUnaryConversions(LHS.get()).get()->getType();
if (ResultTy->isRealFloatingType() &&
- (getLangOpts().getFPRoundingMode() != LangOptions::FPR_ToNearest ||
+ (getLangOpts().getFPRoundingMode() != RoundingMode::NearestTiesToEven ||
getLangOpts().getFPExceptionMode() != LangOptions::FPE_Ignore))
// Mark the current function as usng floating point constrained intrinsics
if (FunctionDecl *F = dyn_cast<FunctionDecl>(CurContext)) {
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 22a3771..1027673 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -89,6 +89,7 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -139,6 +140,7 @@
using namespace clang::serialization;
using namespace clang::serialization::reader;
using llvm::BitstreamCursor;
+using llvm::RoundingMode;
//===----------------------------------------------------------------------===//
// ChainedASTReaderListener implementation