Now compiler defines 5 sets of constants to represent rounding mode.
These are:
- llvm::APFloatBase::roundingMode. It specifies all 5 rounding modes
defined by IEEE-754 and is used in APFloat implementation.
- 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.
- 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.
- 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.
- 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.
I agree that we should use one enum across LLVM and Clang. I'm not sure that using the FLT_ROUNDS values is worthwhile, especially since (1) FLT_ROUNDS doesn't specify a value for some of these (like NearestTiesToAway) and (2) some of the values it does use (e.g. for "indeterminable") make this actively more awkward to store. And the most useful thing we could do — matching the values of FE_TONEAREST and so on — isn't possible because those values are unportable. I'd rather we just pick arbitrary, non-ABI-stable values, like we normally would, and then make the places that rely on matching some external schema translate.