sepavloff created this revision.
sepavloff added reviewers: rjmccall, andrew.w.kaylor, arsenm, kpn, 
cameron.mcinally, uweigand.
Herald added subscribers: dexonsmith, hiraditya, wdng.
Herald added a project: clang.

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 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 defines a special value to
indicate errors. It is convenient to use in intrinsic functions, as it
is a 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 types via one enumeration
`llvm::RoundingMode`, which also contains rounding mode for IEEE
rounding direction `roundTiesToAway`. This enumeration uses the encoding
specified by C standard for `FLT_ROUNDS`, as it is the only representation
in which numerical values of rounding modes is fixed.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77379

Files:
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/LangOptions.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Basic/LangOptions.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Serialization/ASTReader.cpp
  llvm/include/llvm/ADT/APFloat.h
  llvm/include/llvm/ADT/FloatingPointMode.h
  llvm/include/llvm/IR/FPEnv.h
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/IR/IntrinsicInst.h
  llvm/lib/Analysis/ConstantFolding.cpp
  llvm/lib/IR/FPEnv.cpp
  llvm/lib/IR/IntrinsicInst.cpp
  llvm/lib/Support/APFloat.cpp
  llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
  llvm/unittests/IR/IRBuilderTest.cpp

Index: llvm/unittests/IR/IRBuilderTest.cpp
===================================================================
--- llvm/unittests/IR/IRBuilderTest.cpp
+++ llvm/unittests/IR/IRBuilderTest.cpp
@@ -257,51 +257,51 @@
   ASSERT_TRUE(isa<ConstrainedFPIntrinsic>(V));
   auto *CII = cast<ConstrainedFPIntrinsic>(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<ConstrainedFPIntrinsic>(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<ConstrainedFPIntrinsic>(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<ConstrainedFPIntrinsic>(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<ConstrainedFPIntrinsic>(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<ConstrainedFPIntrinsic>(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<ConstrainedFPIntrinsic>(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));
Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ 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;
Index: llvm/lib/Support/APFloat.cpp
===================================================================
--- llvm/lib/Support/APFloat.cpp
+++ 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");
 }
Index: llvm/lib/IR/IntrinsicInst.cpp
===================================================================
--- llvm/lib/IR/IntrinsicInst.cpp
+++ llvm/lib/IR/IntrinsicInst.cpp
@@ -104,7 +104,7 @@
   return ConstantInt::get(Type::getInt64Ty(Context), 1);
 }
 
-Optional<fp::RoundingMode> ConstrainedFPIntrinsic::getRoundingMode() const {
+Optional<RoundingMode> ConstrainedFPIntrinsic::getRoundingMode() const {
   unsigned NumOperands = getNumArgOperands();
   Metadata *MD =
       cast<MetadataAsValue>(getArgOperand(NumOperands - 2))->getMetadata();
Index: llvm/lib/IR/FPEnv.cpp
===================================================================
--- llvm/lib/IR/FPEnv.cpp
+++ llvm/lib/IR/FPEnv.cpp
@@ -17,36 +17,42 @@
 
 namespace llvm {
 
-Optional<fp::RoundingMode> StrToRoundingMode(StringRef RoundingArg) {
+Optional<RoundingMode> 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<Optional<fp::RoundingMode>>(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<Optional<RoundingMode>>(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<StringRef> RoundingModeToStr(fp::RoundingMode UseRounding) {
+Optional<StringRef> RoundingModeToStr(RoundingMode UseRounding) {
   Optional<StringRef> 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<APFloatBase::roundingMode>
-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");
-}
 }
Index: llvm/lib/Analysis/ConstantFolding.cpp
===================================================================
--- llvm/lib/Analysis/ConstantFolding.cpp
+++ llvm/lib/Analysis/ConstantFolding.cpp
@@ -1825,10 +1825,8 @@
     case Intrinsic::experimental_constrained_nearbyint:
     case Intrinsic::experimental_constrained_rint: {
       auto CI = cast<ConstrainedFPIntrinsic>(Call);
-      Optional<fp::RoundingMode> RMOp = CI->getRoundingMode();
-      if (RMOp)
-        RM = getAPFloatRoundingMode(*RMOp);
-      if (!RM)
+      RM = CI->getRoundingMode();
+      if (!RM || RM.getValue() == RoundingMode::Dynamic)
         return nullptr;
       break;
     }
Index: llvm/include/llvm/IR/IntrinsicInst.h
===================================================================
--- llvm/include/llvm/IR/IntrinsicInst.h
+++ llvm/include/llvm/IR/IntrinsicInst.h
@@ -253,7 +253,7 @@
   public:
     bool isUnaryOp() const;
     bool isTernaryOp() const;
-    Optional<fp::RoundingMode> getRoundingMode() const;
+    Optional<RoundingMode> getRoundingMode() const;
     Optional<fp::ExceptionBehavior> getExceptionBehavior() const;
 
     // Methods for support type inquiry through isa, cast, and dyn_cast:
Index: llvm/include/llvm/IR/IRBuilder.h
===================================================================
--- llvm/include/llvm/IR/IRBuilder.h
+++ llvm/include/llvm/IR/IRBuilder.h
@@ -105,7 +105,7 @@
 
   bool IsFPConstrained;
   fp::ExceptionBehavior DefaultConstrainedExcept;
-  fp::RoundingMode DefaultConstrainedRounding;
+  RoundingMode DefaultConstrainedRounding;
 
   ArrayRef<OperandBundleDef> 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;
   }
 
@@ -1217,8 +1217,8 @@
     return (LC && RC) ? Insert(Folder.CreateBinOp(Opc, LC, RC), Name) : nullptr;
   }
 
-  Value *getConstrainedFPRounding(Optional<fp::RoundingMode> Rounding) {
-    fp::RoundingMode UseRounding = DefaultConstrainedRounding;
+  Value *getConstrainedFPRounding(Optional<RoundingMode> Rounding) {
+    RoundingMode UseRounding = DefaultConstrainedRounding;
 
     if (Rounding.hasValue())
       UseRounding = Rounding.getValue();
@@ -1609,7 +1609,7 @@
   CallInst *CreateConstrainedFPBinOp(
       Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource = nullptr,
       const Twine &Name = "", MDNode *FPMathTag = nullptr,
-      Optional<fp::RoundingMode> Rounding = None,
+      Optional<RoundingMode> Rounding = None,
       Optional<fp::ExceptionBehavior> Except = None) {
     Value *RoundingV = getConstrainedFPRounding(Rounding);
     Value *ExceptV = getConstrainedFPExcept(Except);
@@ -2267,7 +2267,7 @@
       Intrinsic::ID ID, Value *V, Type *DestTy,
       Instruction *FMFSource = nullptr, const Twine &Name = "",
       MDNode *FPMathTag = nullptr,
-      Optional<fp::RoundingMode> Rounding = None,
+      Optional<RoundingMode> Rounding = None,
       Optional<fp::ExceptionBehavior> Except = None) {
     Value *ExceptV = getConstrainedFPExcept(Except);
 
@@ -2541,7 +2541,7 @@
 
   CallInst *CreateConstrainedFPCall(
       Function *Callee, ArrayRef<Value *> Args, const Twine &Name = "",
-      Optional<fp::RoundingMode> Rounding = None,
+      Optional<RoundingMode> Rounding = None,
       Optional<fp::ExceptionBehavior> Except = None) {
     llvm::SmallVector<Value *, 6> UseArgs;
 
Index: llvm/include/llvm/IR/FPEnv.h
===================================================================
--- llvm/include/llvm/IR/FPEnv.h
+++ 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<fp::RoundingMode> StrToRoundingMode(StringRef);
+Optional<RoundingMode> StrToRoundingMode(StringRef);
 
 /// For any RoundingMode enumerator, returns a string valid as input in
 /// constrained intrinsic rounding mode metadata.
-Optional<StringRef> RoundingModeToStr(fp::RoundingMode);
+Optional<StringRef> 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<StringRef> 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<APFloatBase::roundingMode> getAPFloatRoundingMode(fp::RoundingMode);
 }
 #endif
Index: llvm/include/llvm/ADT/FloatingPointMode.h
===================================================================
--- llvm/include/llvm/ADT/FloatingPointMode.h
+++ llvm/include/llvm/ADT/FloatingPointMode.h
@@ -18,6 +18,25 @@
 
 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 rounding modes must agree with the values used by FLT_ROUNDS
+/// (C11, 5.2.4.2.2p8).
+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 {
Index: llvm/include/llvm/ADT/APFloat.h
===================================================================
--- llvm/include/llvm/ADT/APFloat.h
+++ 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 <memory>
 
@@ -182,13 +183,13 @@
   };
 
   /// 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.
   ///
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ 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
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ 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.
@@ -13468,7 +13469,7 @@
     return ExprError();
 
   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)) {
Index: clang/lib/Sema/SemaAttr.cpp
===================================================================
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -940,7 +940,7 @@
   }
 }
 
-void Sema::setRoundingMode(LangOptions::FPRoundingModeKind FPR) {
+void Sema::setRoundingMode(llvm::RoundingMode FPR) {
   FPFeatures.setRoundingMode(FPR);
 }
 
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ 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);
 
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ 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);
   }
 }
Index: clang/lib/Basic/LangOptions.cpp
===================================================================
--- clang/lib/Basic/LangOptions.cpp
+++ clang/lib/Basic/LangOptions.cpp
@@ -16,7 +16,8 @@
 
 LangOptions::LangOptions() {
 #define LANGOPT(Name, Bits, Default, Description) Name = Default;
-#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default);
+#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+  set##Name(Type::Default);
 #include "clang/Basic/LangOptions.def"
 }
 
@@ -24,7 +25,7 @@
 #define LANGOPT(Name, Bits, Default, Description)
 #define BENIGN_LANGOPT(Name, Bits, Default, Description) Name = Default;
 #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
-  Name = Default;
+  Name = static_cast<unsigned>(Type::Default);
 #include "clang/Basic/LangOptions.def"
 
   // These options do not affect AST generation.
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -9594,7 +9594,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);
Index: clang/include/clang/Basic/LangOptions.h
===================================================================
--- clang/include/clang/Basic/LangOptions.h
+++ 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();
   }
Index: clang/include/clang/Basic/LangOptions.def
===================================================================
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -121,7 +121,7 @@
 LANGOPT(WritableStrings   , 1, 0, "writable string support")
 LANGOPT(ConstStrings      , 1, 0, "const-qualified string support")
 ENUM_LANGOPT(LaxVectorConversions, LaxVectorConversionKind, 2,
-             LaxVectorConversionKind::All, "lax vector conversions")
+             All, "lax vector conversions")
 LANGOPT(ConvergentFunctions, 1, 1, "Assume convergent functions")
 LANGOPT(AltiVec           , 1, 0, "AltiVec-style vector initializers")
 LANGOPT(ZVector           , 1, 0, "System z vector extensions")
@@ -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, 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")
@@ -293,7 +293,7 @@
 BENIGN_LANGOPT(SemanticInterposition        , 1, 0, "semantic interposition")
 ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,
              "stack protector mode")
-ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized,
+ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, Uninitialized,
              "trivial automatic variable initialization")
 ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
              "signed integer overflow handling")
@@ -313,7 +313,7 @@
 BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0,
         "if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.")
 VALUE_LANGOPT(MSCompatibilityVersion, 32, 0, "Microsoft Visual C/C++ Version")
-ENUM_LANGOPT(VtorDispMode, MSVtorDispMode, 2, MSVtorDispMode::ForVBaseOverride,
+ENUM_LANGOPT(VtorDispMode, MSVtorDispMode, 2, ForVBaseOverride,
              "How many vtordisps to insert")
 
 LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")
@@ -339,7 +339,7 @@
 BENIGN_LANGOPT(AllowEditorPlaceholders, 1, 0,
                "allow editor placeholders in source")
 
-ENUM_LANGOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest,
+ENUM_LANGOPT(ClangABICompat, ClangABI, 4, Latest,
              "version of Clang that we should attempt to be ABI-compatible "
              "with")
 
@@ -353,9 +353,9 @@
 
 COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0")
 
-ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, SignReturnAddressScopeKind::None,
+ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, None,
              "Scope of return address signing")
-ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, SignReturnAddressKeyKind::AKey,
+ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, AKey,
              "Key used for return address signing")
 LANGOPT(BranchTargetEnforcement, 1, 0, "Branch-target enforcement enabled")
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to