Skip to content

Commit aeaac93

Browse files
committed
[APFloat] Add exp function for APFloat::IEEESsingle using expf implementation from LLVM libc.
1 parent 0a0960d commit aeaac93

File tree

7 files changed

+79
-1
lines changed

7 files changed

+79
-1
lines changed

llvm/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,17 @@ endif()
644644

645645
set(LLVM_ENABLE_Z3_SOLVER_DEFAULT "${Z3_FOUND}")
646646

647+
set(LLVM_INTEGRATE_LIBC "OFF" CACHE STRING "Use LLVM libc codes directly if available.")
648+
649+
if(LLVM_INTEGRATE_LIBC)
650+
message(STATUS "LLVM_INTEGRATE_LIBC is ${LLVM_INTEGRATE_LIBC}")
651+
include(FindLibcCommonUtils)
652+
if(NOT TARGET llvm-libc-common-utilities)
653+
message(STATUS "LLVM_INTEGRATE_LIBC is set but cannot find LLVM libc at ${libc_path}.")
654+
set(LLVM_INTEGRATE_LIBC OFF)
655+
endif()
656+
endif()
657+
647658

648659
if( LLVM_TARGETS_TO_BUILD STREQUAL "all" )
649660
set( LLVM_TARGETS_TO_BUILD ${LLVM_ALL_TARGETS} )

llvm/include/llvm/ADT/APFloat.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,7 @@ class APFloat : public APFloatBase {
15221522
friend int ilogb(const APFloat &Arg) { return ilogb(Arg.getIEEE()); }
15231523
friend APFloat scalbn(APFloat X, int Exp, roundingMode RM);
15241524
friend APFloat frexp(const APFloat &X, int &Exp, roundingMode RM);
1525+
friend APFloat exp(const APFloat &X, roundingMode RM);
15251526
friend IEEEFloat;
15261527
friend DoubleAPFloat;
15271528
};
@@ -1657,6 +1658,10 @@ inline APFloat maximumnum(const APFloat &A, const APFloat &B) {
16571658
return A < B ? B : A;
16581659
}
16591660

1661+
/// Implement IEEE 754-2019 exp functions.
1662+
LLVM_READONLY
1663+
APFloat exp(const APFloat &X, RoundingMode RM);
1664+
16601665
inline raw_ostream &operator<<(raw_ostream &OS, const APFloat &V) {
16611666
V.print(OS);
16621667
return OS;

llvm/include/llvm/Config/llvm-config.h.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,7 @@
137137
coverage bugs, and to 0 otherwise. */
138138
#cmakedefine01 LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
139139

140+
/* Define if LLVM and clang uses LLVM libc for math computations. */
141+
#cmakedefine LLVM_INTEGRATE_LIBC
142+
140143
#endif

llvm/lib/Support/APFloat.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
#include <cstring>
2929
#include <limits.h>
3030

31+
#ifdef LLVM_INTEGRATE_LIBC
32+
// Shared headers from LLVM libc
33+
#include "shared/math.h"
34+
#endif // LLVM_INTEGRATE_LIBC
35+
3136
#define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \
3237
do { \
3338
if (usesLayout<IEEEFloat>(getSemantics())) \
@@ -5601,6 +5606,35 @@ float APFloat::convertToFloat() const {
56015606
return Temp.getIEEE().convertToFloat();
56025607
}
56035608

5609+
#ifdef LLVM_INTEGRATE_LIBC
5610+
APFloat exp(const APFloat &X, RoundingMode rounding_mode) {
5611+
assert((&X.getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) &&
5612+
"Float semantics is not IEEEsingle");
5613+
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);
5632+
return APFloat(result);
5633+
}
5634+
llvm_unreachable("Unexpected semantics");
5635+
}
5636+
#endif // LLVM_INTEGRATE_LIBC
5637+
56045638
} // namespace llvm
56055639

56065640
#undef APFLOAT_DISPATCH_ON_SEMANTICS

llvm/lib/Support/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,9 @@ if(LLVM_WITH_Z3)
379379
${Z3_INCLUDE_DIR}
380380
)
381381
endif()
382+
383+
if(LLVM_INTEGRATE_LIBC)
384+
set_property(TARGET LLVMSupport PROPERTY CXX_STANDARD 17)
385+
target_include_directories(LLVMSupport PRIVATE "${LLVM_INCLUDE_DIR}/../../libc")
386+
target_compile_options(LLVMSupport PRIVATE "-Wno-c99-extensions") # _Complex warnings.
387+
endif()

llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,7 @@ bool AMDGPULibCalls::evaluateScalarMathFunc(const FuncInfo &FInfo, double &Res0,
15401540
return true;
15411541

15421542
case AMDGPULibFunc::EI_EXP:
1543-
Res0 = exp(opr0);
1543+
Res0 = std::exp(opr0);
15441544
return true;
15451545

15461546
case AMDGPULibFunc::EI_EXP2:

llvm/unittests/ADT/APFloatTest.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8356,4 +8356,23 @@ TEST(APFloatTest, hasSignBitInMSB) {
83568356
EXPECT_FALSE(APFloat::hasSignBitInMSB(APFloat::Float8E8M0FNU()));
83578357
}
83588358

8359+
#ifdef LLVM_INTEGRATE_LIBC
8360+
TEST(APFloatTest, expf) {
8361+
EXPECT_EQ(
8362+
1.0f,
8363+
llvm::exp(APFloat(0.0f), APFloat::rmNearestTiesToEven).convertToFloat());
8364+
EXPECT_EQ(
8365+
0x1.5bf0a8p1f,
8366+
llvm::exp(APFloat(1.0f), APFloat::rmNearestTiesToEven).convertToFloat());
8367+
EXPECT_EQ(
8368+
0x1.5bf0aap1f,
8369+
llvm::exp(APFloat(1.0f), APFloat::rmTowardPositive).convertToFloat());
8370+
EXPECT_EQ(
8371+
0x1.5bf0a8p1f,
8372+
llvm::exp(APFloat(1.0f), APFloat::rmTowardNegative).convertToFloat());
8373+
EXPECT_EQ(0x1.5bf0a8p1f,
8374+
llvm::exp(APFloat(1.0f), APFloat::rmTowardZero).convertToFloat());
8375+
}
8376+
#endif // LLVM_INTEGRATE_LIBC
8377+
83598378
} // namespace

0 commit comments

Comments
 (0)