[FPEnv] Use typed accessors in FPOptions

Previously methods `FPOptions::get*` returned unsigned value even if the
corresponding property was represented by specific enumeration type. With
this change such methods return actual type of the property. It also
allows printing value of a property as text rather than integer code.

Differential Revision: https://reviews.llvm.org/D87812
This commit is contained in:
Serge Pavlov 2020-09-16 23:27:46 +07:00
parent 5a733468e0
commit 8a86261c51
4 changed files with 30 additions and 13 deletions

View File

@ -14,7 +14,7 @@
// OPTION(name, type, width, previousName)
OPTION(FPContractMode, LangOptions::FPModeKind, 2, First)
OPTION(RoundingMode, RoundingMode, 3, FPContractMode)
OPTION(RoundingMode, LangOptions::RoundingMode, 3, FPContractMode)
OPTION(FPExceptionMode, LangOptions::FPExceptionModeKind, 2, RoundingMode)
OPTION(AllowFEnvAccess, bool, 1, FPExceptionMode)
OPTION(AllowFPReassociate, bool, 1, AllowFEnvAccess)

View File

@ -432,8 +432,7 @@ public:
}
bool isFPConstrained() const {
return getRoundingMode() !=
static_cast<unsigned>(RoundingMode::NearestTiesToEven) ||
return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven ||
getFPExceptionMode() != LangOptions::FPE_Ignore ||
getAllowFEnvAccess();
}
@ -453,8 +452,8 @@ public:
// We can define most of the accessors automatically:
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
unsigned get##NAME() const { \
return static_cast<unsigned>(TYPE((Value & NAME##Mask) >> NAME##Shift)); \
TYPE get##NAME() const { \
return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift); \
} \
void set##NAME(TYPE value) { \
Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \
@ -561,7 +560,7 @@ public:
bool has##NAME##Override() const { \
return OverrideMask & FPOptions::NAME##Mask; \
} \
unsigned get##NAME##Override() const { \
TYPE get##NAME##Override() const { \
assert(has##NAME##Override()); \
return Options.get##NAME(); \
} \

View File

@ -87,7 +87,7 @@ float func_10(float x, float y) {
}
// CHECK-LABEL: FunctionDecl {{.*}} func_10 'float (float, float)'
// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=3
// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=downward
float func_11(float x, float y) {
if (x < 0) {
@ -98,8 +98,8 @@ float func_11(float x, float y) {
}
// CHECK-LABEL: FunctionDecl {{.*}} func_11 'float (float, float)'
// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=2
// CHECK: BinaryOperator {{.*}} 'float' '-' RoundingMode=3
// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=upward
// CHECK: BinaryOperator {{.*}} 'float' '-' RoundingMode=downward
#pragma STDC FENV_ROUND FE_DYNAMIC
@ -109,7 +109,7 @@ float func_12(float x, float y) {
}
// CHECK-LABEL: FunctionDecl {{.*}} func_12 'float (float, float)'
// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=1
// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=tonearest
#pragma STDC FENV_ROUND FE_TONEAREST
@ -118,7 +118,7 @@ float func_13(float x, float y) {
}
// CHECK-LABEL: FunctionDecl {{.*}} func_13 'float (float, float)'
// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=1
// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=tonearest
template <typename T>
@ -136,8 +136,8 @@ float func_15(float x, float y) {
// CHECK: FunctionDecl {{.*}} func_14 'T (T, T)'
// CHECK: CompoundStmt
// CHECK-NEXT: ReturnStmt
// CHECK-NEXT: BinaryOperator {{.*}} '+' RoundingMode=0
// CHECK-NEXT: BinaryOperator {{.*}} '+' RoundingMode=towardzero
// CHECK: FunctionDecl {{.*}} func_14 'float (float, float)'
// CHECK: CompoundStmt
// CHECK-NEXT: ReturnStmt
// CHECK-NEXT: BinaryOperator {{.*}} 'float' '+' RoundingMode=0
// CHECK-NEXT: BinaryOperator {{.*}} 'float' '+' RoundingMode=towardzero

View File

@ -44,6 +44,24 @@ enum class RoundingMode : int8_t {
Invalid = -1 ///< Denotes invalid value.
};
/// Returns text representation of the given rounding mode.
inline StringRef spell(RoundingMode RM) {
switch (RM) {
case RoundingMode::TowardZero: return "towardzero";
case RoundingMode::NearestTiesToEven: return "tonearest";
case RoundingMode::TowardPositive: return "upward";
case RoundingMode::TowardNegative: return "downward";
case RoundingMode::NearestTiesToAway: return "tonearestaway";
case RoundingMode::Dynamic: return "dynamic";
default: return "invalid";
}
}
inline raw_ostream &operator << (raw_ostream &OS, RoundingMode RM) {
OS << spell(RM);
return OS;
}
/// Represent subnormal handling kind for floating point instruction inputs and
/// outputs.
struct DenormalMode {