arsenm created this revision. arsenm added reviewers: sepavloff, rjmccall, kpn, cameron.mcinally, uweigand, scanon, jcranmer-intel, foad. Herald added subscribers: StephenFan, tpr. Herald added a project: All. arsenm requested review of this revision. Herald added a subscriber: wdng. Herald added a project: LLVM.
FLT_ROUNDS says -1 is used for "the default rounding direction is not known". The previous 7 was taking away options in the "implementation-defined behavior" range if you just wanted to extend the enum. AMDGPU has 2 separately controllable rounding modes that change different fp types. I want to stick to the standard values in the case the modes are the same, and use the extended range for cases where the two are different. Dodging this gap in the enum value required defining the AMDGPU target specific values in a weird way with strange conversion code to handle it (see https://reviews.llvm.org/D153257). https://reviews.llvm.org/D156989 Files: clang/include/clang/Basic/FPOptions.def clang/include/clang/Basic/LangOptions.h clang/lib/AST/JSONNodeDumper.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/Basic/LangOptions.cpp llvm/include/llvm/ADT/FloatingPointMode.h
Index: llvm/include/llvm/ADT/FloatingPointMode.h =================================================================== --- llvm/include/llvm/ADT/FloatingPointMode.h +++ llvm/include/llvm/ADT/FloatingPointMode.h @@ -35,18 +35,30 @@ /// rounding mode value, so it does not need to fit the bit fields. /// enum class RoundingMode : int8_t { + // Special values. + Invalid = -2, + + ///< Denotes mode unknown at compile time. + Dynamic = -1, + // Rounding mode defined in IEEE-754. TowardZero = 0, ///< roundTowardZero. NearestTiesToEven = 1, ///< roundTiesToEven. TowardPositive = 2, ///< roundTowardPositive. TowardNegative = 3, ///< roundTowardNegative. - NearestTiesToAway = 4, ///< roundTiesToAway. - - // Special values. - Dynamic = 7, ///< Denotes mode unknown at compile time. - Invalid = -1 ///< Denotes invalid value. + NearestTiesToAway = 4 ///< roundTiesToAway. }; +/// Encode a RoundingMode value into a form suitable for a bitfield. +constexpr int8_t encodeRoundingMode(RoundingMode RM) { + return static_cast<int8_t>(RM) + 1; +} + +/// Decode a RoundingMode value from a form suitable for a bitfield. +constexpr RoundingMode decodeRoundingMode(int8_t Val) { + return static_cast<RoundingMode>(Val - 1); +} + /// Returns text representation of the given rounding mode. inline StringRef spell(RoundingMode RM) { switch (RM) { Index: clang/lib/Basic/LangOptions.cpp =================================================================== --- clang/lib/Basic/LangOptions.cpp +++ clang/lib/Basic/LangOptions.cpp @@ -215,7 +215,7 @@ FPOptionsOverride FPOptions::getChangesSlow(const FPOptions &Base) const { FPOptions::storage_type OverrideMask = 0; -#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ +#define OPTION(NAME, TYPE, ENCODE, DECODE, WIDTH, PREVIOUS) \ if (get##NAME() != Base.get##NAME()) \ OverrideMask |= NAME##Mask; #include "clang/Basic/FPOptions.def" @@ -223,14 +223,14 @@ } LLVM_DUMP_METHOD void FPOptions::dump() { -#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ +#define OPTION(NAME, TYPE, ENCODE, DECODE, WIDTH, PREVIOUS) \ llvm::errs() << "\n " #NAME " " << get##NAME(); #include "clang/Basic/FPOptions.def" llvm::errs() << "\n"; } LLVM_DUMP_METHOD void FPOptionsOverride::dump() { -#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ +#define OPTION(NAME, TYPE, ENCODE, DECODE, WIDTH, PREVIOUS) \ if (has##NAME##Override()) \ llvm::errs() << "\n " #NAME " Override is " << get##NAME##Override(); #include "clang/Basic/FPOptions.def" Index: clang/lib/AST/TextNodeDumper.cpp =================================================================== --- clang/lib/AST/TextNodeDumper.cpp +++ clang/lib/AST/TextNodeDumper.cpp @@ -756,7 +756,7 @@ } void TextNodeDumper::printFPOptions(FPOptionsOverride FPO) { -#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ +#define OPTION(NAME, TYPE, ENCODE, DECODE, WIDTH, PREVIOUS) \ if (FPO.has##NAME##Override()) \ OS << " " #NAME "=" << FPO.get##NAME##Override(); #include "clang/Basic/FPOptions.def" Index: clang/lib/AST/JSONNodeDumper.cpp =================================================================== --- clang/lib/AST/JSONNodeDumper.cpp +++ clang/lib/AST/JSONNodeDumper.cpp @@ -1740,7 +1740,7 @@ llvm::json::Object JSONNodeDumper::createFPOptions(FPOptionsOverride FPO) { llvm::json::Object Ret; -#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ +#define OPTION(NAME, TYPE, ENCODE, DECODE, WIDTH, PREVIOUS) \ if (FPO.has##NAME##Override()) \ Ret.try_emplace(#NAME, static_cast<unsigned>(FPO.get##NAME##Override())); #include "clang/Basic/FPOptions.def" Index: clang/include/clang/Basic/LangOptions.h =================================================================== --- clang/include/clang/Basic/LangOptions.h +++ clang/include/clang/Basic/LangOptions.h @@ -670,7 +670,7 @@ // Define a fake option named "First" so that we have a PREVIOUS even for the // real first option. static constexpr storage_type FirstShift = 0, FirstWidth = 0; -#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ +#define OPTION(NAME, ENCODE, DECODE, TYPE, WIDTH, PREVIOUS) \ static constexpr storage_type NAME##Shift = \ PREVIOUS##Shift + PREVIOUS##Width; \ static constexpr storage_type NAME##Width = WIDTH; \ @@ -679,7 +679,7 @@ #include "clang/Basic/FPOptions.def" static constexpr storage_type TotalWidth = 0 -#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH +#define OPTION(NAME, ENCODE, DECODE, TYPE, WIDTH, PREVIOUS) +WIDTH #include "clang/Basic/FPOptions.def" ; static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions"); @@ -783,12 +783,13 @@ FPOptionsOverride getChangesFrom(const FPOptions &Base) const; // We can define most of the accessors automatically: -#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ +#define OPTION(NAME, TYPE, ENCODE, DECODE, WIDTH, PREVIOUS) \ TYPE get##NAME() const { \ - return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift); \ + return DECODE((Value & NAME##Mask) >> NAME##Shift); \ } \ void set##NAME(TYPE value) { \ - Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \ + Value = \ + (Value & ~NAME##Mask) | (storage_type(ENCODE(value)) << NAME##Shift); \ } #include "clang/Basic/FPOptions.def" LLVM_DUMP_METHOD void dump(); @@ -890,7 +891,7 @@ } bool operator!=(FPOptionsOverride other) const { return !(*this == other); } -#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ +#define OPTION(NAME, TYPE, ENCODE, DECODE, WIDTH, PREVIOUS) \ bool has##NAME##Override() const { \ return OverrideMask & FPOptions::NAME##Mask; \ } \ Index: clang/include/clang/Basic/FPOptions.def =================================================================== --- clang/include/clang/Basic/FPOptions.def +++ clang/include/clang/Basic/FPOptions.def @@ -12,19 +12,24 @@ # error Define the OPTION macro to handle floating point language options #endif +#define SIMPLE_OPTION(name, type, width, previousName) \ + OPTION(name, type, static_cast<type>, static_cast<type>, width, previousName) + // OPTION(name, type, width, previousName) -OPTION(FPContractMode, LangOptions::FPModeKind, 2, First) -OPTION(RoundingMath, bool, 1, FPContractMode) -OPTION(ConstRoundingMode, LangOptions::RoundingMode, 3, RoundingMath) -OPTION(SpecifiedExceptionMode, LangOptions::FPExceptionModeKind, 2, ConstRoundingMode) -OPTION(AllowFEnvAccess, bool, 1, SpecifiedExceptionMode) -OPTION(AllowFPReassociate, bool, 1, AllowFEnvAccess) -OPTION(NoHonorNaNs, bool, 1, AllowFPReassociate) -OPTION(NoHonorInfs, bool, 1, NoHonorNaNs) -OPTION(NoSignedZero, bool, 1, NoHonorInfs) -OPTION(AllowReciprocal, bool, 1, NoSignedZero) -OPTION(AllowApproxFunc, bool, 1, AllowReciprocal) -OPTION(FPEvalMethod, LangOptions::FPEvalMethodKind, 2, AllowApproxFunc) -OPTION(Float16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, FPEvalMethod) -OPTION(BFloat16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, FPEvalMethod) +SIMPLE_OPTION(FPContractMode, LangOptions::FPModeKind, 2, First) +SIMPLE_OPTION(RoundingMath, bool, 1, FPContractMode) +OPTION(ConstRoundingMode, LangOptions::RoundingMode, llvm::encodeRoundingMode, llvm::decodeRoundingMode, 3, RoundingMath) +SIMPLE_OPTION(SpecifiedExceptionMode, LangOptions::FPExceptionModeKind, 2, ConstRoundingMode) +SIMPLE_OPTION(AllowFEnvAccess, bool, 1, SpecifiedExceptionMode) +SIMPLE_OPTION(AllowFPReassociate, bool, 1, AllowFEnvAccess) +SIMPLE_OPTION(NoHonorNaNs, bool, 1, AllowFPReassociate) +SIMPLE_OPTION(NoHonorInfs, bool, 1, NoHonorNaNs) +SIMPLE_OPTION(NoSignedZero, bool, 1, NoHonorInfs) +SIMPLE_OPTION(AllowReciprocal, bool, 1, NoSignedZero) +SIMPLE_OPTION(AllowApproxFunc, bool, 1, AllowReciprocal) +SIMPLE_OPTION(FPEvalMethod, LangOptions::FPEvalMethodKind, 2, AllowApproxFunc) +SIMPLE_OPTION(Float16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, FPEvalMethod) +SIMPLE_OPTION(BFloat16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, FPEvalMethod) + +#undef SIMPLE_OPTION #undef OPTION
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits