diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h --- 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 @@ -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(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(I & 3)), - fenv_access(static_cast((I >> 2) & 1)), - rounding(static_cast((I >> 3) & 7)), - exceptions(static_cast((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(rounding); + RoundingMode getRoundingMode() const { + return static_cast(rounding); } - void setRoundingMode(LangOptions::FPRoundingModeKind RM) { - rounding = RM; + void setRoundingMode(RoundingMode RM) { + rounding = static_cast(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/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def --- 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/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- 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 --- 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 --- 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 --- 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 --- 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(CurContext)) { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp --- 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 diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -16556,6 +16556,7 @@ "round.downward" "round.upward" "round.towardzero" + "round.tonearestaway" If this argument is "round.dynamic" optimization passes must assume that the rounding mode is unknown and may change at runtime. No transformations that diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h --- a/llvm/include/llvm/ADT/APFloat.h +++ b/llvm/include/llvm/ADT/APFloat.h @@ -18,6 +18,7 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FloatingPointMode.h" #include "llvm/Support/ErrorHandling.h" #include @@ -182,13 +183,15 @@ }; /// IEEE-754R 4.3: Rounding-direction attributes. - enum roundingMode { - rmNearestTiesToEven, - rmTowardPositive, - rmTowardNegative, - rmTowardZero, - rmNearestTiesToAway - }; + using roundingMode = llvm::RoundingMode; + + static constexpr roundingMode rmNearestTiesToEven = + RoundingMode::NearestTiesToEven; + static constexpr roundingMode rmTowardPositive = RoundingMode::TowardPositive; + static constexpr roundingMode rmTowardNegative = RoundingMode::TowardNegative; + static constexpr roundingMode rmTowardZero = RoundingMode::TowardZero; + static constexpr roundingMode rmNearestTiesToAway = + RoundingMode::NearestTiesToAway; /// IEEE-754R 7: Default exception handling. /// diff --git a/llvm/include/llvm/ADT/FloatingPointMode.h b/llvm/include/llvm/ADT/FloatingPointMode.h --- a/llvm/include/llvm/ADT/FloatingPointMode.h +++ b/llvm/include/llvm/ADT/FloatingPointMode.h @@ -18,6 +18,32 @@ namespace llvm { +/// Rounding mode. +/// +/// Enumerates supported rounding modes, as well as some special values. The set +/// of the modes must agree with IEEE-754, 4.3.1 and 4.3.2. The constants +/// assigned to the IEEE rounding modes must agree with the values used by +/// FLT_ROUNDS (C11, 5.2.4.2.2p8). +/// +/// This value is packed into bitfield in some cases, including \c FPOptions, so +/// the rounding mode values and the special value \c Dynamic must fit into the +/// the bit field (now - 3 bits). The value \c Invalid is used only in values +/// returned by intrinsics to indicate errors, it should never be stored as +/// rounding mode value, so it does not need to fit the bit fields. +/// +enum class RoundingMode : int8_t { + // 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. +}; + /// Represent ssubnormal handling kind for floating point instruction inputs and /// outputs. struct DenormalMode { diff --git a/llvm/include/llvm/IR/FPEnv.h b/llvm/include/llvm/IR/FPEnv.h --- a/llvm/include/llvm/IR/FPEnv.h +++ b/llvm/include/llvm/IR/FPEnv.h @@ -24,19 +24,6 @@ namespace fp { -/// Rounding mode used for floating point operations. -/// -/// Each of these values correspond to some metadata argument value of a -/// constrained floating point intrinsic. See the LLVM Language Reference Manual -/// for details. -enum RoundingMode : uint8_t { - rmDynamic, ///< This corresponds to "fpround.dynamic". - rmToNearest, ///< This corresponds to "fpround.tonearest". - rmDownward, ///< This corresponds to "fpround.downward". - rmUpward, ///< This corresponds to "fpround.upward". - rmTowardZero ///< This corresponds to "fpround.tozero". -}; - /// Exception behavior used for floating point operations. /// /// Each of these values correspond to some metadata argument value of a @@ -53,11 +40,11 @@ /// Returns a valid RoundingMode enumerator when given a string /// that is valid as input in constrained intrinsic rounding mode /// metadata. -Optional StrToRoundingMode(StringRef); +Optional StrToRoundingMode(StringRef); /// For any RoundingMode enumerator, returns a string valid as input in /// constrained intrinsic rounding mode metadata. -Optional RoundingModeToStr(fp::RoundingMode); +Optional RoundingModeToStr(RoundingMode); /// Returns a valid ExceptionBehavior enumerator when given a string /// valid as input in constrained intrinsic exception behavior metadata. @@ -66,9 +53,5 @@ /// For any ExceptionBehavior enumerator, returns a string valid as /// input in constrained intrinsic exception behavior metadata. Optional ExceptionBehaviorToStr(fp::ExceptionBehavior); - -/// Converts rounding mode represented by fp::RoundingMode to the rounding mode -/// index used by APFloat. For fp::rmDynamic it returns None. -Optional getAPFloatRoundingMode(fp::RoundingMode); } #endif diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -105,7 +105,7 @@ bool IsFPConstrained; fp::ExceptionBehavior DefaultConstrainedExcept; - fp::RoundingMode DefaultConstrainedRounding; + RoundingMode DefaultConstrainedRounding; ArrayRef DefaultOperandBundles; @@ -116,7 +116,7 @@ : Context(context), Folder(Folder), Inserter(Inserter), DefaultFPMathTag(FPMathTag), IsFPConstrained(false), DefaultConstrainedExcept(fp::ebStrict), - DefaultConstrainedRounding(fp::rmDynamic), + DefaultConstrainedRounding(RoundingMode::Dynamic), DefaultOperandBundles(OpBundles) { ClearInsertionPoint(); } @@ -268,7 +268,7 @@ } /// Set the rounding mode handling to be used with constrained floating point - void setDefaultConstrainedRounding(fp::RoundingMode NewRounding) { + void setDefaultConstrainedRounding(RoundingMode NewRounding) { DefaultConstrainedRounding = NewRounding; } @@ -278,7 +278,7 @@ } /// Get the rounding mode handling used with constrained floating point - fp::RoundingMode getDefaultConstrainedRounding() { + RoundingMode getDefaultConstrainedRounding() { return DefaultConstrainedRounding; } @@ -1130,8 +1130,8 @@ return (LC && RC) ? Insert(Folder.CreateBinOp(Opc, LC, RC), Name) : nullptr; } - Value *getConstrainedFPRounding(Optional Rounding) { - fp::RoundingMode UseRounding = DefaultConstrainedRounding; + Value *getConstrainedFPRounding(Optional Rounding) { + RoundingMode UseRounding = DefaultConstrainedRounding; if (Rounding.hasValue()) UseRounding = Rounding.getValue(); @@ -1522,7 +1522,7 @@ CallInst *CreateConstrainedFPBinOp( Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource = nullptr, const Twine &Name = "", MDNode *FPMathTag = nullptr, - Optional Rounding = None, + Optional Rounding = None, Optional Except = None); Value *CreateNeg(Value *V, const Twine &Name = "", @@ -2145,7 +2145,7 @@ Intrinsic::ID ID, Value *V, Type *DestTy, Instruction *FMFSource = nullptr, const Twine &Name = "", MDNode *FPMathTag = nullptr, - Optional Rounding = None, + Optional Rounding = None, Optional Except = None); // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a @@ -2368,7 +2368,7 @@ CallInst *CreateConstrainedFPCall( Function *Callee, ArrayRef Args, const Twine &Name = "", - Optional Rounding = None, + Optional Rounding = None, Optional Except = None); Value *CreateSelect(Value *C, Value *True, Value *False, diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h --- a/llvm/include/llvm/IR/IntrinsicInst.h +++ b/llvm/include/llvm/IR/IntrinsicInst.h @@ -253,7 +253,7 @@ public: bool isUnaryOp() const; bool isTernaryOp() const; - Optional getRoundingMode() const; + Optional getRoundingMode() const; Optional getExceptionBehavior() const; // Methods for support type inquiry through isa, cast, and dyn_cast: diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1828,10 +1828,8 @@ case Intrinsic::experimental_constrained_nearbyint: case Intrinsic::experimental_constrained_rint: { auto CI = cast(Call); - Optional RMOp = CI->getRoundingMode(); - if (RMOp) - RM = getAPFloatRoundingMode(*RMOp); - if (!RM) + RM = CI->getRoundingMode(); + if (!RM || RM.getValue() == RoundingMode::Dynamic) return nullptr; break; } diff --git a/llvm/lib/IR/FPEnv.cpp b/llvm/lib/IR/FPEnv.cpp --- a/llvm/lib/IR/FPEnv.cpp +++ b/llvm/lib/IR/FPEnv.cpp @@ -17,36 +17,42 @@ namespace llvm { -Optional StrToRoundingMode(StringRef RoundingArg) { +Optional StrToRoundingMode(StringRef RoundingArg) { // For dynamic rounding mode, we use round to nearest but we will set the // 'exact' SDNodeFlag so that the value will not be rounded. - return StringSwitch>(RoundingArg) - .Case("round.dynamic", fp::rmDynamic) - .Case("round.tonearest", fp::rmToNearest) - .Case("round.downward", fp::rmDownward) - .Case("round.upward", fp::rmUpward) - .Case("round.towardzero", fp::rmTowardZero) + return StringSwitch>(RoundingArg) + .Case("round.dynamic", RoundingMode::Dynamic) + .Case("round.tonearest", RoundingMode::NearestTiesToEven) + .Case("round.tonearestaway", RoundingMode::NearestTiesToAway) + .Case("round.downward", RoundingMode::TowardNegative) + .Case("round.upward", RoundingMode::TowardPositive) + .Case("round.towardzero", RoundingMode::TowardZero) .Default(None); } -Optional RoundingModeToStr(fp::RoundingMode UseRounding) { +Optional RoundingModeToStr(RoundingMode UseRounding) { Optional RoundingStr = None; switch (UseRounding) { - case fp::rmDynamic: + case RoundingMode::Dynamic: RoundingStr = "round.dynamic"; break; - case fp::rmToNearest: + case RoundingMode::NearestTiesToEven: RoundingStr = "round.tonearest"; break; - case fp::rmDownward: + case RoundingMode::NearestTiesToAway: + RoundingStr = "round.tonearestaway"; + break; + case RoundingMode::TowardNegative: RoundingStr = "round.downward"; break; - case fp::rmUpward: + case RoundingMode::TowardPositive: RoundingStr = "round.upward"; break; - case fp::rmTowardZero: + case RoundingMode::TowardZero: RoundingStr = "round.towardzero"; break; + default: + break; } return RoundingStr; } @@ -74,21 +80,4 @@ } return ExceptStr; } - -Optional -getAPFloatRoundingMode(fp::RoundingMode RM) { - switch (RM) { - case fp::rmDynamic: - return None; - case fp::rmToNearest: - return APFloat::rmNearestTiesToEven; - case fp::rmDownward: - return APFloat::rmTowardNegative; - case fp::rmUpward: - return APFloat::rmTowardPositive; - case fp::rmTowardZero: - return APFloat::rmTowardZero; - } - llvm_unreachable("Unexpected rounding mode"); -} } diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp --- a/llvm/lib/IR/IRBuilder.cpp +++ b/llvm/lib/IR/IRBuilder.cpp @@ -760,7 +760,7 @@ CallInst *IRBuilderBase::CreateConstrainedFPBinOp( Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource, const Twine &Name, MDNode *FPMathTag, - Optional Rounding, + Optional Rounding, Optional Except) { Value *RoundingV = getConstrainedFPRounding(Rounding); Value *ExceptV = getConstrainedFPExcept(Except); @@ -794,7 +794,7 @@ CallInst *IRBuilderBase::CreateConstrainedFPCast( Intrinsic::ID ID, Value *V, Type *DestTy, Instruction *FMFSource, const Twine &Name, MDNode *FPMathTag, - Optional Rounding, + Optional Rounding, Optional Except) { Value *ExceptV = getConstrainedFPExcept(Except); @@ -857,7 +857,7 @@ CallInst *IRBuilderBase::CreateConstrainedFPCall( Function *Callee, ArrayRef Args, const Twine &Name, - Optional Rounding, + Optional Rounding, Optional Except) { llvm::SmallVector UseArgs; diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp --- a/llvm/lib/IR/IntrinsicInst.cpp +++ b/llvm/lib/IR/IntrinsicInst.cpp @@ -104,7 +104,7 @@ return ConstantInt::get(Type::getInt64Ty(Context), 1); } -Optional ConstrainedFPIntrinsic::getRoundingMode() const { +Optional ConstrainedFPIntrinsic::getRoundingMode() const { unsigned NumOperands = getNumArgOperands(); Metadata *MD = cast(getArgOperand(NumOperands - 2))->getMetadata(); diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp --- a/llvm/lib/Support/APFloat.cpp +++ b/llvm/lib/Support/APFloat.cpp @@ -171,6 +171,12 @@ return semPPCDoubleDouble; } + constexpr RoundingMode APFloatBase::rmNearestTiesToEven; + constexpr RoundingMode APFloatBase::rmTowardPositive; + constexpr RoundingMode APFloatBase::rmTowardNegative; + constexpr RoundingMode APFloatBase::rmTowardZero; + constexpr RoundingMode APFloatBase::rmNearestTiesToAway; + /* A tight upper bound on number of parts required to hold the value pow(5, power) is @@ -1323,6 +1329,9 @@ case rmTowardNegative: return sign; + + default: + break; } llvm_unreachable("Invalid rounding mode found"); } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -270,7 +270,7 @@ } void FAddendCoef::operator+=(const FAddendCoef &That) { - enum APFloat::roundingMode RndMode = APFloat::rmNearestTiesToEven; + RoundingMode RndMode = RoundingMode::NearestTiesToEven; if (isInt() == That.isInt()) { if (isInt()) IntVal += That.IntVal; diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp --- a/llvm/unittests/IR/IRBuilderTest.cpp +++ b/llvm/unittests/IR/IRBuilderTest.cpp @@ -257,51 +257,51 @@ ASSERT_TRUE(isa(V)); auto *CII = cast(V); EXPECT_EQ(fp::ebStrict, CII->getExceptionBehavior()); - EXPECT_EQ(fp::rmDynamic, CII->getRoundingMode()); + EXPECT_EQ(RoundingMode::Dynamic, CII->getRoundingMode()); Builder.setDefaultConstrainedExcept(fp::ebIgnore); - Builder.setDefaultConstrainedRounding(fp::rmUpward); + Builder.setDefaultConstrainedRounding(RoundingMode::TowardPositive); V = Builder.CreateFAdd(V, V); CII = cast(V); EXPECT_EQ(fp::ebIgnore, CII->getExceptionBehavior()); - EXPECT_EQ(CII->getRoundingMode(), fp::rmUpward); + EXPECT_EQ(CII->getRoundingMode(), RoundingMode::TowardPositive); Builder.setDefaultConstrainedExcept(fp::ebIgnore); - Builder.setDefaultConstrainedRounding(fp::rmToNearest); + Builder.setDefaultConstrainedRounding(RoundingMode::NearestTiesToEven); V = Builder.CreateFAdd(V, V); CII = cast(V); EXPECT_EQ(fp::ebIgnore, CII->getExceptionBehavior()); - EXPECT_EQ(fp::rmToNearest, CII->getRoundingMode()); + EXPECT_EQ(RoundingMode::NearestTiesToEven, CII->getRoundingMode()); Builder.setDefaultConstrainedExcept(fp::ebMayTrap); - Builder.setDefaultConstrainedRounding(fp::rmDownward); + Builder.setDefaultConstrainedRounding(RoundingMode::TowardNegative); V = Builder.CreateFAdd(V, V); CII = cast(V); EXPECT_EQ(fp::ebMayTrap, CII->getExceptionBehavior()); - EXPECT_EQ(fp::rmDownward, CII->getRoundingMode()); + EXPECT_EQ(RoundingMode::TowardNegative, CII->getRoundingMode()); Builder.setDefaultConstrainedExcept(fp::ebStrict); - Builder.setDefaultConstrainedRounding(fp::rmTowardZero); + Builder.setDefaultConstrainedRounding(RoundingMode::TowardZero); V = Builder.CreateFAdd(V, V); CII = cast(V); EXPECT_EQ(fp::ebStrict, CII->getExceptionBehavior()); - EXPECT_EQ(fp::rmTowardZero, CII->getRoundingMode()); + EXPECT_EQ(RoundingMode::TowardZero, CII->getRoundingMode()); Builder.setDefaultConstrainedExcept(fp::ebIgnore); - Builder.setDefaultConstrainedRounding(fp::rmDynamic); + Builder.setDefaultConstrainedRounding(RoundingMode::Dynamic); V = Builder.CreateFAdd(V, V); CII = cast(V); EXPECT_EQ(fp::ebIgnore, CII->getExceptionBehavior()); - EXPECT_EQ(fp::rmDynamic, CII->getRoundingMode()); + EXPECT_EQ(RoundingMode::Dynamic, CII->getRoundingMode()); // Now override the defaults. Call = Builder.CreateConstrainedFPBinOp( Intrinsic::experimental_constrained_fadd, V, V, nullptr, "", nullptr, - fp::rmDownward, fp::ebMayTrap); + RoundingMode::TowardNegative, fp::ebMayTrap); CII = cast(Call); EXPECT_EQ(CII->getIntrinsicID(), Intrinsic::experimental_constrained_fadd); EXPECT_EQ(fp::ebMayTrap, CII->getExceptionBehavior()); - EXPECT_EQ(fp::rmDownward, CII->getRoundingMode()); + EXPECT_EQ(RoundingMode::TowardNegative, CII->getRoundingMode()); Builder.CreateRetVoid(); EXPECT_FALSE(verifyModule(*M));