[llvm] c7ff5b3 - [FPEnv] Use single enum to represent rounding mode
Serge Pavlov via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 8 23:27:48 PDT 2020
Author: Serge Pavlov
Date: 2020-04-09T13:26:47+07:00
New Revision: c7ff5b38f27f812dcd6e2e8732208a39232dc284
URL: https://github.com/llvm/llvm-project/commit/c7ff5b38f27f812dcd6e2e8732208a39232dc284
DIFF: https://github.com/llvm/llvm-project/commit/c7ff5b38f27f812dcd6e2e8732208a39232dc284.diff
LOG: [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
Added:
Modified:
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Sema/Sema.h
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/docs/LangRef.rst
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/IRBuilder.cpp
llvm/lib/IR/IntrinsicInst.cpp
llvm/lib/Support/APFloat.cpp
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/unittests/IR/IRBuilderTest.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 51dc87b0b671..bddd0f0ddcd8 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -263,7 +263,7 @@ LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating poi
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 0a0cbaf80ae8..95b435ba9f34 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 @@ enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable };
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 @@ class LangOptions : public LangOptionsBase {
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 @@ class LangOptions : public LangOptionsBase {
/// 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 @@ class FPOptions {
// 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 @@ class FPOptions {
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 @@ class FPOptions {
}
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 4645ef8d2cd1..f2b0a9534c04 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9592,7 +9592,7 @@ class Sema final {
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 b01a5a4c3685..05bf70e5cb22 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -115,21 +115,6 @@ CodeGenFunction::~CodeGenFunction() {
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 @@ static llvm::fp::ExceptionBehavior ToConstrainedExceptMD(
}
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 23638e16a5b7..cebfb0b3d2af 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 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
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 6a2f74479c48..9141a28381ad 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -940,7 +940,7 @@ void Sema::ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC) {
}
}
-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 5c6b9471da11..6f7ff3729688 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 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
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 22a3771e4b85..10276736414b 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;
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
index 3b2f7a42128f..5c054516c1e8 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -16556,6 +16556,7 @@ by the intrinsic, this argument must be one of the following strings:
"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
index f230cac4b596..37aa6dce7f11 100644
--- 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 <memory>
@@ -182,13 +183,15 @@ struct APFloatBase {
};
/// 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
index fd06789c0f6e..c8c83d8be8d6 100644
--- 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
index 0e7e96ff700a..eadfef2a82f8 100644
--- a/llvm/include/llvm/IR/FPEnv.h
+++ b/llvm/include/llvm/IR/FPEnv.h
@@ -24,19 +24,6 @@ namespace llvm {
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 @@ enum ExceptionBehavior : uint8_t {
/// 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 @@ Optional<fp::ExceptionBehavior> StrToExceptionBehavior(StringRef);
/// 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
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index 5bc31ab67fe0..b7ed3b9055bc 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -105,7 +105,7 @@ class IRBuilderBase {
bool IsFPConstrained;
fp::ExceptionBehavior DefaultConstrainedExcept;
- fp::RoundingMode DefaultConstrainedRounding;
+ RoundingMode DefaultConstrainedRounding;
ArrayRef<OperandBundleDef> DefaultOperandBundles;
@@ -116,7 +116,7 @@ class IRBuilderBase {
: 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 @@ class IRBuilderBase {
}
/// 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 @@ class IRBuilderBase {
}
/// Get the rounding mode handling used with constrained floating point
- fp::RoundingMode getDefaultConstrainedRounding() {
+ RoundingMode getDefaultConstrainedRounding() {
return DefaultConstrainedRounding;
}
@@ -1130,8 +1130,8 @@ class IRBuilderBase {
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();
@@ -1522,7 +1522,7 @@ class IRBuilderBase {
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 *CreateNeg(Value *V, const Twine &Name = "",
@@ -2145,7 +2145,7 @@ class IRBuilderBase {
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);
// Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a
@@ -2368,7 +2368,7 @@ class IRBuilderBase {
CallInst *CreateConstrainedFPCall(
Function *Callee, ArrayRef<Value *> Args, const Twine &Name = "",
- Optional<fp::RoundingMode> Rounding = None,
+ Optional<RoundingMode> Rounding = None,
Optional<fp::ExceptionBehavior> 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
index 81c9cab190ba..4d6319d87817 100644
--- a/llvm/include/llvm/IR/IntrinsicInst.h
+++ b/llvm/include/llvm/IR/IntrinsicInst.h
@@ -253,7 +253,7 @@ namespace llvm {
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:
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index fe84af0ff120..eff153144dda 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1828,10 +1828,8 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
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;
}
diff --git a/llvm/lib/IR/FPEnv.cpp b/llvm/lib/IR/FPEnv.cpp
index ab68f55f834d..40f999e05b98 100644
--- a/llvm/lib/IR/FPEnv.cpp
+++ b/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 @@ Optional<StringRef> ExceptionBehaviorToStr(fp::ExceptionBehavior UseExcept) {
}
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");
-}
}
diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp
index bd16e0da3218..d1d93e7dbe73 100644
--- a/llvm/lib/IR/IRBuilder.cpp
+++ b/llvm/lib/IR/IRBuilder.cpp
@@ -760,7 +760,7 @@ CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
CallInst *IRBuilderBase::CreateConstrainedFPBinOp(
Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource,
const Twine &Name, MDNode *FPMathTag,
- Optional<fp::RoundingMode> Rounding,
+ Optional<RoundingMode> Rounding,
Optional<fp::ExceptionBehavior> Except) {
Value *RoundingV = getConstrainedFPRounding(Rounding);
Value *ExceptV = getConstrainedFPExcept(Except);
@@ -794,7 +794,7 @@ Value *IRBuilderBase::CreateNAryOp(unsigned Opc, ArrayRef<Value *> Ops,
CallInst *IRBuilderBase::CreateConstrainedFPCast(
Intrinsic::ID ID, Value *V, Type *DestTy,
Instruction *FMFSource, const Twine &Name, MDNode *FPMathTag,
- Optional<fp::RoundingMode> Rounding,
+ Optional<RoundingMode> Rounding,
Optional<fp::ExceptionBehavior> Except) {
Value *ExceptV = getConstrainedFPExcept(Except);
@@ -857,7 +857,7 @@ CallInst *IRBuilderBase::CreateConstrainedFPCmp(
CallInst *IRBuilderBase::CreateConstrainedFPCall(
Function *Callee, ArrayRef<Value *> Args, const Twine &Name,
- Optional<fp::RoundingMode> Rounding,
+ Optional<RoundingMode> Rounding,
Optional<fp::ExceptionBehavior> Except) {
llvm::SmallVector<Value *, 6> UseArgs;
diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp
index 1ce17aa63bdb..1ad58fce3564 100644
--- a/llvm/lib/IR/IntrinsicInst.cpp
+++ b/llvm/lib/IR/IntrinsicInst.cpp
@@ -104,7 +104,7 @@ Value *InstrProfIncrementInst::getStep() const {
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();
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 49f9cf8a32f8..63114faae117 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -171,6 +171,12 @@ namespace llvm {
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 @@ bool IEEEFloat::roundAwayFromZero(roundingMode rounding_mode,
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
index 8a143c25112e..3579d31d48a4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -270,7 +270,7 @@ void FAddendCoef::operator=(const FAddendCoef &That) {
}
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
index ab9cec33bac7..b4a7ad3cf391 100644
--- a/llvm/unittests/IR/IRBuilderTest.cpp
+++ b/llvm/unittests/IR/IRBuilderTest.cpp
@@ -257,51 +257,51 @@ TEST_F(IRBuilderTest, ConstrainedFP) {
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));
More information about the llvm-commits
mailing list