Skip to content

Commit d43491b

Browse files
committed
Add directional rounding version to LLVM libc and use that in APFloat.
1 parent 32f6609 commit d43491b

File tree

2 files changed

+27
-19
lines changed

2 files changed

+27
-19
lines changed

libc/src/__support/math/expf.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ static constexpr float expf(float x) {
109109
return static_cast<float>(exp_hi * exp_mid * exp_lo);
110110
}
111111

112+
// Directional rounding version of expf.
113+
LIBC_INLINE static float expf(float x, int rounding_mode) {
114+
int current_rounding_mode = fputil::get_round();
115+
fputil::set_round(rounding_mode);
116+
float result = expf(x);
117+
fputil::set_round(current_rounding_mode);
118+
return result;
119+
}
120+
112121
} // namespace math
113122

114123
} // namespace LIBC_NAMESPACE_DECL

llvm/lib/Support/APFloat.cpp

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5607,28 +5607,27 @@ float APFloat::convertToFloat() const {
56075607
}
56085608

56095609
#ifdef LLVM_INTEGRATE_LIBC
5610-
APFloat exp(const APFloat &X, RoundingMode rounding_mode) {
5610+
static constexpr int getFEnvRoundingMode(llvm::RoundingMode rm) {
5611+
switch (rm) {
5612+
case APFloat::rmTowardPositive:
5613+
return FE_UPWARD;
5614+
case APFloat::rmTowardNegative:
5615+
return FE_DOWNWARD;
5616+
case APFloat::rmTowardZero:
5617+
return FE_TOWARDZERO;
5618+
default:
5619+
// TODO: fix rmNearestTiesToAway for platform without FE_TONEARESTFROMZERO.
5620+
return FE_TONEAREST;
5621+
};
5622+
}
5623+
5624+
APFloat exp(const APFloat &X,
5625+
RoundingMode rounding_mode = APFloat::rmNearestTiesToEven) {
56115626
assert((&X.getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) &&
56125627
"Float semantics is not IEEEsingle");
56135628
if (&X.getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) {
5614-
int current_rounding_mode = fegetround();
5615-
switch (rounding_mode) {
5616-
case APFloat::rmNearestTiesToEven:
5617-
fesetround(FE_TONEAREST);
5618-
break;
5619-
case APFloat::rmTowardPositive:
5620-
fesetround(FE_UPWARD);
5621-
break;
5622-
case APFloat::rmTowardNegative:
5623-
fesetround(FE_DOWNWARD);
5624-
break;
5625-
case APFloat::rmTowardZero:
5626-
fesetround(FE_TOWARDZERO);
5627-
break;
5628-
default:
5629-
}
5630-
float result = LIBC_NAMESPACE::shared::expf(X.convertToFloat());
5631-
fesetround(current_rounding_mode);
5629+
float result = LIBC_NAMESPACE::shared::expf(
5630+
X.convertToFloat(), getFEnvRoundingMode(rounding_mode));
56325631
return APFloat(result);
56335632
}
56345633
llvm_unreachable("Unexpected semantics");

0 commit comments

Comments
 (0)