-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[APFloat] Add exp function for APFloat::IEEESsingle using expf implementation from LLVM libc. #143959
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[APFloat] Add exp function for APFloat::IEEESsingle using expf implementation from LLVM libc. #143959
Changes from 4 commits
aeaac93
32f6609
d43491b
f134cb7
d18947d
79ee1b5
b1ea332
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -644,6 +644,17 @@ endif() | |
|
||
set(LLVM_ENABLE_Z3_SOLVER_DEFAULT "${Z3_FOUND}") | ||
|
||
set(LLVM_INTEGRATE_LIBC "OFF" CACHE STRING "Use LLVM libc code directly if available.") | ||
|
||
if(LLVM_INTEGRATE_LIBC) | ||
message(STATUS "LLVM_INTEGRATE_LIBC is ${LLVM_INTEGRATE_LIBC}") | ||
include(FindLibcCommonUtils) | ||
if(NOT TARGET llvm-libc-common-utilities) | ||
message(STATUS "LLVM_INTEGRATE_LIBC is set but cannot find LLVM libc at ${libc_path}.") | ||
set(LLVM_INTEGRATE_LIBC OFF) | ||
endif() | ||
endif() | ||
|
||
Comment on lines
+647
to
+657
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given that it will not be possible to build a conforming C++ toolchain without that integration, and given that there does not seem to be a noticeable benefit to be able to disable it, + the complexity of testing it... I think we should just have an unconditional dependency here. |
||
|
||
if( LLVM_TARGETS_TO_BUILD STREQUAL "all" ) | ||
set( LLVM_TARGETS_TO_BUILD ${LLVM_ALL_TARGETS} ) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1522,6 +1522,7 @@ class APFloat : public APFloatBase { | |
friend int ilogb(const APFloat &Arg) { return ilogb(Arg.getIEEE()); } | ||
friend APFloat scalbn(APFloat X, int Exp, roundingMode RM); | ||
friend APFloat frexp(const APFloat &X, int &Exp, roundingMode RM); | ||
friend APFloat exp(const APFloat &X, roundingMode RM); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I'm following correctly, we have two separate declarations of this function... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. And added test for using the default rounding mode. |
||
friend IEEEFloat; | ||
friend DoubleAPFloat; | ||
}; | ||
|
@@ -1657,6 +1658,10 @@ inline APFloat maximumnum(const APFloat &A, const APFloat &B) { | |
return A < B ? B : A; | ||
} | ||
|
||
/// Implement IEEE 754-2019 exp functions. | ||
LLVM_READONLY | ||
APFloat exp(const APFloat &X, RoundingMode RM); | ||
|
||
inline raw_ostream &operator<<(raw_ostream &OS, const APFloat &V) { | ||
V.print(OS); | ||
return OS; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,11 @@ | |
#include <cstring> | ||
#include <limits.h> | ||
|
||
#ifdef LLVM_INTEGRATE_LIBC | ||
// Shared headers from LLVM libc | ||
#include "shared/math.h" | ||
#endif // LLVM_INTEGRATE_LIBC | ||
|
||
#define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \ | ||
do { \ | ||
if (usesLayout<IEEEFloat>(getSemantics())) \ | ||
|
@@ -5601,6 +5606,34 @@ float APFloat::convertToFloat() const { | |
return Temp.getIEEE().convertToFloat(); | ||
} | ||
|
||
#ifdef LLVM_INTEGRATE_LIBC | ||
static constexpr int getFEnvRoundingMode(llvm::RoundingMode rm) { | ||
switch (rm) { | ||
case APFloat::rmTowardPositive: | ||
return FE_UPWARD; | ||
case APFloat::rmTowardNegative: | ||
return FE_DOWNWARD; | ||
case APFloat::rmTowardZero: | ||
return FE_TOWARDZERO; | ||
default: | ||
// TODO: fix rmNearestTiesToAway for platform without FE_TONEARESTFROMZERO. | ||
return FE_TONEAREST; | ||
}; | ||
} | ||
|
||
APFloat exp(const APFloat &X, | ||
RoundingMode rounding_mode = APFloat::rmNearestTiesToEven) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... and the default parameter is only in the definition body that no user code sees. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. And added test for using the default rounding modes. |
||
assert((&X.getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) && | ||
"Float semantics is not IEEEsingle"); | ||
if (&X.getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) { | ||
float result = LIBC_NAMESPACE::shared::expf( | ||
X.convertToFloat(), getFEnvRoundingMode(rounding_mode)); | ||
return APFloat(result); | ||
} | ||
llvm_unreachable("Unexpected semantics"); | ||
} | ||
#endif // LLVM_INTEGRATE_LIBC | ||
|
||
} // namespace llvm | ||
|
||
#undef APFLOAT_DISPATCH_ON_SEMANTICS |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -379,3 +379,9 @@ if(LLVM_WITH_Z3) | |
${Z3_INCLUDE_DIR} | ||
) | ||
endif() | ||
|
||
if(LLVM_INTEGRATE_LIBC) | ||
set_property(TARGET LLVMSupport PROPERTY CXX_STANDARD 17) | ||
target_include_directories(LLVMSupport PRIVATE "${LLVM_INCLUDE_DIR}/../../libc") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested this build locally, and somehow the way this was declared caused a fatal include error trying to build APFloat.cpp, complaining that it couldn't find shared/math.h There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's ugly but maybe we can have these return std::optional and just fail out if the support wasn't built? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd expect that this would become a required dependency before we can actually start using it somewhere. |
||
target_compile_options(LLVMSupport PRIVATE "-Wno-c99-extensions") # _Complex warnings. | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the pragma to enable fenv_access?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would still be more comfortable if you just add an exp implementation with a template argument for the rounding mode, and didn't use fenv access anywhere in the stack. This has just merely shuffled the problem into the libc code directly