[libc-commits] [libc] [llvm] [APFloat] Add exp function for APFloat::IEEESsingle using expf implementation from LLVM libc. (PR #143959)
via libc-commits
libc-commits at lists.llvm.org
Sun Jul 20 10:16:02 PDT 2025
https://github.com/lntue updated https://github.com/llvm/llvm-project/pull/143959
>From fd17304dd367b30267a5a9b6b2c209bf869ac9a6 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Thu, 12 Jun 2025 19:53:28 +0000
Subject: [PATCH 1/9] [APFloat] Add exp function for APFloat::IEEESsingle using
expf implementation from LLVM libc.
---
llvm/CMakeLists.txt | 11 +++++++
llvm/include/llvm/ADT/APFloat.h | 5 +++
llvm/include/llvm/Config/llvm-config.h.cmake | 3 ++
llvm/lib/Support/APFloat.cpp | 34 ++++++++++++++++++++
llvm/lib/Support/CMakeLists.txt | 6 ++++
llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp | 2 +-
llvm/unittests/ADT/APFloatTest.cpp | 19 +++++++++++
7 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 903461b39902e..17da93b60ebfb 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -659,6 +659,17 @@ endif()
set(LLVM_ENABLE_Z3_SOLVER_DEFAULT "${Z3_FOUND}")
+set(LLVM_INTEGRATE_LIBC "OFF" CACHE STRING "Use LLVM libc codes 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()
+
if( LLVM_TARGETS_TO_BUILD STREQUAL "all" )
set( LLVM_TARGETS_TO_BUILD ${LLVM_ALL_TARGETS} )
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index e1589544787cf..061264da065ea 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1523,6 +1523,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);
friend IEEEFloat;
friend DoubleAPFloat;
};
@@ -1658,6 +1659,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;
diff --git a/llvm/include/llvm/Config/llvm-config.h.cmake b/llvm/include/llvm/Config/llvm-config.h.cmake
index a6832299e5b6b..c05a717774ada 100644
--- a/llvm/include/llvm/Config/llvm-config.h.cmake
+++ b/llvm/include/llvm/Config/llvm-config.h.cmake
@@ -143,4 +143,7 @@
coverage bugs, and to 0 otherwise. */
#cmakedefine01 LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+/* Define if LLVM and clang uses LLVM libc for math computations. */
+#cmakedefine LLVM_INTEGRATE_LIBC
+
#endif
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 5e0b29ffb2590..150853743540d 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -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,35 @@ float APFloat::convertToFloat() const {
return Temp.getIEEE().convertToFloat();
}
+#ifdef LLVM_INTEGRATE_LIBC
+APFloat exp(const APFloat &X, RoundingMode rounding_mode) {
+ assert((&X.getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) &&
+ "Float semantics is not IEEEsingle");
+ if (&X.getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) {
+ int current_rounding_mode = fegetround();
+ switch (rounding_mode) {
+ case APFloat::rmNearestTiesToEven:
+ fesetround(FE_TONEAREST);
+ break;
+ case APFloat::rmTowardPositive:
+ fesetround(FE_UPWARD);
+ break;
+ case APFloat::rmTowardNegative:
+ fesetround(FE_DOWNWARD);
+ break;
+ case APFloat::rmTowardZero:
+ fesetround(FE_TOWARDZERO);
+ break;
+ default:
+ }
+ float result = LIBC_NAMESPACE::shared::expf(X.convertToFloat());
+ fesetround(current_rounding_mode);
+ return APFloat(result);
+ }
+ llvm_unreachable("Unexpected semantics");
+}
+#endif // LLVM_INTEGRATE_LIBC
+
} // namespace llvm
#undef APFLOAT_DISPATCH_ON_SEMANTICS
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index 10b6101d73277..a82fd39c58c90 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -384,3 +384,9 @@ target_include_directories(LLVMSupport
PRIVATE
${LLVM_THIRD_PARTY_DIR}/siphash/include
)
+
+if(LLVM_INTEGRATE_LIBC)
+ set_property(TARGET LLVMSupport PROPERTY CXX_STANDARD 17)
+ target_include_directories(LLVMSupport PRIVATE "${LLVM_INCLUDE_DIR}/../../libc")
+ target_compile_options(LLVMSupport PRIVATE "-Wno-c99-extensions") # _Complex warnings.
+endif()
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
index 8767208d20ec9..1e2aa2839fc8f 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
@@ -1540,7 +1540,7 @@ bool AMDGPULibCalls::evaluateScalarMathFunc(const FuncInfo &FInfo, double &Res0,
return true;
case AMDGPULibFunc::EI_EXP:
- Res0 = exp(opr0);
+ Res0 = std::exp(opr0);
return true;
case AMDGPULibFunc::EI_EXP2:
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index 7a5fd83cd9581..c56cd8898d17a 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -8356,4 +8356,23 @@ TEST(APFloatTest, hasSignBitInMSB) {
EXPECT_FALSE(APFloat::hasSignBitInMSB(APFloat::Float8E8M0FNU()));
}
+#ifdef LLVM_INTEGRATE_LIBC
+TEST(APFloatTest, expf) {
+ EXPECT_EQ(
+ 1.0f,
+ llvm::exp(APFloat(0.0f), APFloat::rmNearestTiesToEven).convertToFloat());
+ EXPECT_EQ(
+ 0x1.5bf0a8p1f,
+ llvm::exp(APFloat(1.0f), APFloat::rmNearestTiesToEven).convertToFloat());
+ EXPECT_EQ(
+ 0x1.5bf0aap1f,
+ llvm::exp(APFloat(1.0f), APFloat::rmTowardPositive).convertToFloat());
+ EXPECT_EQ(
+ 0x1.5bf0a8p1f,
+ llvm::exp(APFloat(1.0f), APFloat::rmTowardNegative).convertToFloat());
+ EXPECT_EQ(0x1.5bf0a8p1f,
+ llvm::exp(APFloat(1.0f), APFloat::rmTowardZero).convertToFloat());
+}
+#endif // LLVM_INTEGRATE_LIBC
+
} // namespace
>From ac2be1bd005ae9febfccf353793476c422debc20 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Fri, 13 Jun 2025 04:09:15 +0000
Subject: [PATCH 2/9] Fix typo and add more tests.
---
llvm/CMakeLists.txt | 2 +-
llvm/unittests/ADT/APFloatTest.cpp | 53 ++++++++++++++++++++++++++++--
2 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 17da93b60ebfb..6df0ebc9f1004 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -659,7 +659,7 @@ endif()
set(LLVM_ENABLE_Z3_SOLVER_DEFAULT "${Z3_FOUND}")
-set(LLVM_INTEGRATE_LIBC "OFF" CACHE STRING "Use LLVM libc codes directly if available.")
+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}")
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index c56cd8898d17a..f7e5a64ba9306 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -16,6 +16,7 @@
#include "llvm/Support/FormatVariadic.h"
#include "gtest/gtest.h"
#include <cmath>
+#include <limits>
#include <ostream>
#include <string>
#include <tuple>
@@ -8358,9 +8359,24 @@ TEST(APFloatTest, hasSignBitInMSB) {
#ifdef LLVM_INTEGRATE_LIBC
TEST(APFloatTest, expf) {
- EXPECT_EQ(
- 1.0f,
- llvm::exp(APFloat(0.0f), APFloat::rmNearestTiesToEven).convertToFloat());
+ std::array<llvm::RoundingMode, 4> allRoundingModes = {
+ APFloat::rmNearestTiesToEven, APFloat::rmTowardPositive,
+ APFloat::rmTowardNegative, APFloat::rmTowardZero};
+ for (auto rm : allRoundingModes) {
+ // exp(+-0) = 1 for all rounding modes.
+ EXPECT_EQ(1.0f, llvm::exp(APFloat(0.0f), rm).convertToFloat());
+ EXPECT_EQ(1.0f, llvm::exp(APFloat(-0.0f), rm).convertToFloat());
+ // exp(+Inf) = +Inf for all rounding modes.
+ EXPECT_EQ(std::numeric_limits<float>::infinity(),
+ llvm::exp(APFloat::getInf(APFloat::IEEEsingle(), false), rm)
+ .convertToFloat());
+ // exp(-Inf) = 0 for all rounding modes.
+ EXPECT_EQ(0.0f, llvm::exp(APFloat::getInf(APFloat::IEEEsingle(), true), rm)
+ .convertToFloat());
+ // exp(NaN) = NaN for all rounding modes.
+ EXPECT_TRUE(llvm::exp(APFloat::getNaN(APFloat::IEEEsingle()), rm).isNaN());
+ }
+ // exp(1)
EXPECT_EQ(
0x1.5bf0a8p1f,
llvm::exp(APFloat(1.0f), APFloat::rmNearestTiesToEven).convertToFloat());
@@ -8372,6 +8388,37 @@ TEST(APFloatTest, expf) {
llvm::exp(APFloat(1.0f), APFloat::rmTowardNegative).convertToFloat());
EXPECT_EQ(0x1.5bf0a8p1f,
llvm::exp(APFloat(1.0f), APFloat::rmTowardZero).convertToFloat());
+ // exp(float max)
+ EXPECT_EQ(std::numeric_limits<float>::infinity(),
+ llvm::exp(APFloat::getLargest(APFloat::IEEEsingle(), false),
+ APFloat::rmNearestTiesToEven)
+ .convertToFloat());
+ EXPECT_EQ(std::numeric_limits<float>::infinity(),
+ llvm::exp(APFloat::getLargest(APFloat::IEEEsingle(), false),
+ APFloat::rmTowardPositive)
+ .convertToFloat());
+ EXPECT_EQ(std::numeric_limits<float>::max(),
+ llvm::exp(APFloat::getLargest(APFloat::IEEEsingle(), false),
+ APFloat::rmTowardNegative)
+ .convertToFloat());
+ EXPECT_EQ(std::numeric_limits<float>::max(),
+ llvm::exp(APFloat::getLargest(APFloat::IEEEsingle(), false),
+ APFloat::rmTowardZero)
+ .convertToFloat());
+ // exp(min_denormal)
+ EXPECT_EQ(1.0f, llvm::exp(APFloat::getSmallest(APFloat::IEEEsingle(), false),
+ APFloat::rmNearestTiesToEven)
+ .convertToFloat());
+ EXPECT_EQ(0x1.000002p0,
+ llvm::exp(APFloat::getSmallest(APFloat::IEEEsingle(), false),
+ APFloat::rmTowardPositive)
+ .convertToFloat());
+ EXPECT_EQ(1.0f, llvm::exp(APFloat::getSmallest(APFloat::IEEEsingle(), false),
+ APFloat::rmTowardNegative)
+ .convertToFloat());
+ EXPECT_EQ(1.0f, llvm::exp(APFloat::getSmallest(APFloat::IEEEsingle(), false),
+ APFloat::rmTowardZero)
+ .convertToFloat());
}
#endif // LLVM_INTEGRATE_LIBC
>From 83dcbad2acc945997d6a162182e69522c7ddc2e7 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Fri, 13 Jun 2025 14:16:20 +0000
Subject: [PATCH 3/9] Add directional rounding version to LLVM libc and use
that in APFloat.
---
libc/src/__support/math/expf.h | 9 +++++++++
llvm/lib/Support/APFloat.cpp | 37 +++++++++++++++++-----------------
2 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/libc/src/__support/math/expf.h b/libc/src/__support/math/expf.h
index 88c151492a041..d401993a75fc9 100644
--- a/libc/src/__support/math/expf.h
+++ b/libc/src/__support/math/expf.h
@@ -109,6 +109,15 @@ static constexpr float expf(float x) {
return static_cast<float>(exp_hi * exp_mid * exp_lo);
}
+// Directional rounding version of expf.
+LIBC_INLINE static float expf(float x, int rounding_mode) {
+ int current_rounding_mode = fputil::get_round();
+ fputil::set_round(rounding_mode);
+ float result = expf(x);
+ fputil::set_round(current_rounding_mode);
+ return result;
+}
+
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 150853743540d..574d0c233c425 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -5607,28 +5607,27 @@ float APFloat::convertToFloat() const {
}
#ifdef LLVM_INTEGRATE_LIBC
-APFloat exp(const APFloat &X, RoundingMode rounding_mode) {
+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) {
assert((&X.getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) &&
"Float semantics is not IEEEsingle");
if (&X.getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) {
- int current_rounding_mode = fegetround();
- switch (rounding_mode) {
- case APFloat::rmNearestTiesToEven:
- fesetround(FE_TONEAREST);
- break;
- case APFloat::rmTowardPositive:
- fesetround(FE_UPWARD);
- break;
- case APFloat::rmTowardNegative:
- fesetround(FE_DOWNWARD);
- break;
- case APFloat::rmTowardZero:
- fesetround(FE_TOWARDZERO);
- break;
- default:
- }
- float result = LIBC_NAMESPACE::shared::expf(X.convertToFloat());
- fesetround(current_rounding_mode);
+ float result = LIBC_NAMESPACE::shared::expf(
+ X.convertToFloat(), getFEnvRoundingMode(rounding_mode));
return APFloat(result);
}
llvm_unreachable("Unexpected semantics");
>From f2d662ccc2a48be99f18fb874ded0c98f2e0ae28 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Fri, 13 Jun 2025 14:21:45 +0000
Subject: [PATCH 4/9] Only change rounding modes if they are different.
---
libc/src/__support/math/expf.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/libc/src/__support/math/expf.h b/libc/src/__support/math/expf.h
index d401993a75fc9..6b0498428bd13 100644
--- a/libc/src/__support/math/expf.h
+++ b/libc/src/__support/math/expf.h
@@ -112,6 +112,9 @@ static constexpr float expf(float x) {
// Directional rounding version of expf.
LIBC_INLINE static float expf(float x, int rounding_mode) {
int current_rounding_mode = fputil::get_round();
+ if (rounding_mode == current_rounding_mode)
+ return expf(x);
+
fputil::set_round(rounding_mode);
float result = expf(x);
fputil::set_round(current_rounding_mode);
>From ea9e1e01c39be759c3f9f9dc6a69ba287ac16a49 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Fri, 13 Jun 2025 15:36:32 +0000
Subject: [PATCH 5/9] Omit declarations when LLVM_INTEGRATE_LIBC is off and fix
default rounding mode declaration.
---
llvm/include/llvm/ADT/APFloat.h | 9 +++++++--
llvm/lib/Support/APFloat.cpp | 3 +--
llvm/unittests/ADT/APFloatTest.cpp | 13 ++++++++++++-
3 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index 061264da065ea..a935c204514be 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1523,9 +1523,12 @@ 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);
friend IEEEFloat;
friend DoubleAPFloat;
+
+#ifdef LLVM_INTEGRATE_LIBC
+ friend APFloat exp(const APFloat &X, roundingMode RM);
+#endif // LLVM_INTEGRATE_LIBC)
};
static_assert(sizeof(APFloat) == sizeof(detail::IEEEFloat),
@@ -1659,9 +1662,11 @@ inline APFloat maximumnum(const APFloat &A, const APFloat &B) {
return A < B ? B : A;
}
+#ifdef LLVM_INTEGRATE_LIBC
/// Implement IEEE 754-2019 exp functions.
LLVM_READONLY
-APFloat exp(const APFloat &X, RoundingMode RM);
+APFloat exp(const APFloat &X, RoundingMode RM = APFloat::rmNearestTiesToEven);
+#endif // LLVM_INTEGRATE_LIBC
inline raw_ostream &operator<<(raw_ostream &OS, const APFloat &V) {
V.print(OS);
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 574d0c233c425..d2948d37a5cf0 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -5621,8 +5621,7 @@ static constexpr int getFEnvRoundingMode(llvm::RoundingMode rm) {
};
}
-APFloat exp(const APFloat &X,
- RoundingMode rounding_mode = APFloat::rmNearestTiesToEven) {
+APFloat exp(const APFloat &X, RoundingMode rounding_mode) {
assert((&X.getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) &&
"Float semantics is not IEEEsingle");
if (&X.getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) {
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index f7e5a64ba9306..3eef9287b8abf 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -8409,7 +8409,7 @@ TEST(APFloatTest, expf) {
EXPECT_EQ(1.0f, llvm::exp(APFloat::getSmallest(APFloat::IEEEsingle(), false),
APFloat::rmNearestTiesToEven)
.convertToFloat());
- EXPECT_EQ(0x1.000002p0,
+ EXPECT_EQ(0x1.000002p0f,
llvm::exp(APFloat::getSmallest(APFloat::IEEEsingle(), false),
APFloat::rmTowardPositive)
.convertToFloat());
@@ -8419,6 +8419,17 @@ TEST(APFloatTest, expf) {
EXPECT_EQ(1.0f, llvm::exp(APFloat::getSmallest(APFloat::IEEEsingle(), false),
APFloat::rmTowardZero)
.convertToFloat());
+ // Default rounding mode.
+ // exp(-1)
+ EXPECT_EQ(0x1.78b564p-2f, llvm::exp(APFloat(-1.0f)).convertToFloat());
+ EXPECT_EQ(
+ 0x1.78b564p-2f,
+ llvm::exp(APFloat(-1.0f), APFloat::rmTowardPositive).convertToFloat());
+ EXPECT_EQ(
+ 0x1.78b562p-2f,
+ llvm::exp(APFloat(-1.0f), APFloat::rmTowardNegative).convertToFloat());
+ EXPECT_EQ(0x1.78b562p-2f,
+ llvm::exp(APFloat(-1.0f), APFloat::rmTowardZero).convertToFloat());
}
#endif // LLVM_INTEGRATE_LIBC
>From d2f48ce7b80b2fd51d39df055236549dc3928b0b Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Fri, 13 Jun 2025 18:23:28 +0000
Subject: [PATCH 6/9] Remove trailing ).
---
llvm/include/llvm/ADT/APFloat.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index a935c204514be..6f68feca4cb9f 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1528,7 +1528,7 @@ class APFloat : public APFloatBase {
#ifdef LLVM_INTEGRATE_LIBC
friend APFloat exp(const APFloat &X, roundingMode RM);
-#endif // LLVM_INTEGRATE_LIBC)
+#endif // LLVM_INTEGRATE_LIBC
};
static_assert(sizeof(APFloat) == sizeof(detail::IEEEFloat),
>From d45f55d799be90d9f9fc64eb9b3187e0eccbff01 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Sun, 15 Jun 2025 01:35:19 +0000
Subject: [PATCH 7/9] Wrap static rounding expf function with #pragma STDC
FENV_ACCESS ON
---
libc/src/__support/math/expf.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/libc/src/__support/math/expf.h b/libc/src/__support/math/expf.h
index 6b0498428bd13..f3accce54885f 100644
--- a/libc/src/__support/math/expf.h
+++ b/libc/src/__support/math/expf.h
@@ -109,6 +109,8 @@ static constexpr float expf(float x) {
return static_cast<float>(exp_hi * exp_mid * exp_lo);
}
+#pragma STDC FENV_ACCESS ON
+
// Directional rounding version of expf.
LIBC_INLINE static float expf(float x, int rounding_mode) {
int current_rounding_mode = fputil::get_round();
@@ -121,6 +123,8 @@ LIBC_INLINE static float expf(float x, int rounding_mode) {
return result;
}
+#pragma STDC FENV_ACCESS DEFAULT
+
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
>From 2e7aea32cca5a61fd5790e1b3d653293ccd9671f Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Fri, 18 Jul 2025 20:44:27 +0000
Subject: [PATCH 8/9] Make LLVM libc a required dependency and address
comments.
---
llvm/CMakeLists.txt | 12 +++---------
llvm/include/llvm/ADT/APFloat.h | 4 ----
llvm/include/llvm/Config/llvm-config.h.cmake | 3 ---
llvm/lib/Support/APFloat.cpp | 8 +-------
llvm/lib/Support/CMakeLists.txt | 9 ++++-----
llvm/unittests/ADT/APFloatTest.cpp | 2 --
6 files changed, 8 insertions(+), 30 deletions(-)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 6df0ebc9f1004..18595072e3b41 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -659,15 +659,9 @@ 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()
+include(FindLibcCommonUtils)
+if(NOT TARGET llvm-libc-common-utilities)
+ message(FATAL_ERROR "LLVM libc is not found at ${libc_path}.")
endif()
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index 6f68feca4cb9f..cd472c416ff9e 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1526,9 +1526,7 @@ class APFloat : public APFloatBase {
friend IEEEFloat;
friend DoubleAPFloat;
-#ifdef LLVM_INTEGRATE_LIBC
friend APFloat exp(const APFloat &X, roundingMode RM);
-#endif // LLVM_INTEGRATE_LIBC
};
static_assert(sizeof(APFloat) == sizeof(detail::IEEEFloat),
@@ -1662,11 +1660,9 @@ inline APFloat maximumnum(const APFloat &A, const APFloat &B) {
return A < B ? B : A;
}
-#ifdef LLVM_INTEGRATE_LIBC
/// Implement IEEE 754-2019 exp functions.
LLVM_READONLY
APFloat exp(const APFloat &X, RoundingMode RM = APFloat::rmNearestTiesToEven);
-#endif // LLVM_INTEGRATE_LIBC
inline raw_ostream &operator<<(raw_ostream &OS, const APFloat &V) {
V.print(OS);
diff --git a/llvm/include/llvm/Config/llvm-config.h.cmake b/llvm/include/llvm/Config/llvm-config.h.cmake
index c05a717774ada..a6832299e5b6b 100644
--- a/llvm/include/llvm/Config/llvm-config.h.cmake
+++ b/llvm/include/llvm/Config/llvm-config.h.cmake
@@ -143,7 +143,4 @@
coverage bugs, and to 0 otherwise. */
#cmakedefine01 LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
-/* Define if LLVM and clang uses LLVM libc for math computations. */
-#cmakedefine LLVM_INTEGRATE_LIBC
-
#endif
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index d2948d37a5cf0..0c4d7d455b4ca 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -28,10 +28,8 @@
#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 { \
@@ -5606,7 +5604,6 @@ float APFloat::convertToFloat() const {
return Temp.getIEEE().convertToFloat();
}
-#ifdef LLVM_INTEGRATE_LIBC
static constexpr int getFEnvRoundingMode(llvm::RoundingMode rm) {
switch (rm) {
case APFloat::rmTowardPositive:
@@ -5622,16 +5619,13 @@ static constexpr int getFEnvRoundingMode(llvm::RoundingMode rm) {
}
APFloat exp(const APFloat &X, RoundingMode rounding_mode) {
- 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");
+ assert(false && "Unsupported floating-point semantics");
}
-#endif // LLVM_INTEGRATE_LIBC
} // namespace llvm
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index a82fd39c58c90..ca7448a2ece94 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -385,8 +385,7 @@ target_include_directories(LLVMSupport
${LLVM_THIRD_PARTY_DIR}/siphash/include
)
-if(LLVM_INTEGRATE_LIBC)
- set_property(TARGET LLVMSupport PROPERTY CXX_STANDARD 17)
- target_include_directories(LLVMSupport PRIVATE "${LLVM_INCLUDE_DIR}/../../libc")
- target_compile_options(LLVMSupport PRIVATE "-Wno-c99-extensions") # _Complex warnings.
-endif()
+# Integrating LLVM libc's math functions
+set_property(TARGET LLVMSupport PROPERTY CXX_STANDARD 17)
+target_include_directories(LLVMSupport PRIVATE "${LLVM_INCLUDE_DIR}/../../libc")
+target_compile_options(LLVMSupport PRIVATE "-Wno-c99-extensions") # _Complex warnings.
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index 3eef9287b8abf..79d940a15d4c7 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -8357,7 +8357,6 @@ TEST(APFloatTest, hasSignBitInMSB) {
EXPECT_FALSE(APFloat::hasSignBitInMSB(APFloat::Float8E8M0FNU()));
}
-#ifdef LLVM_INTEGRATE_LIBC
TEST(APFloatTest, expf) {
std::array<llvm::RoundingMode, 4> allRoundingModes = {
APFloat::rmNearestTiesToEven, APFloat::rmTowardPositive,
@@ -8431,6 +8430,5 @@ TEST(APFloatTest, expf) {
EXPECT_EQ(0x1.78b562p-2f,
llvm::exp(APFloat(-1.0f), APFloat::rmTowardZero).convertToFloat());
}
-#endif // LLVM_INTEGRATE_LIBC
} // namespace
>From 1d07dc9fb51d97e5a7815dd4f60e5c0047dfb845 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Sun, 20 Jul 2025 17:14:38 +0000
Subject: [PATCH 9/9] Address comments.
---
llvm/lib/Support/APFloat.cpp | 2 +-
llvm/lib/Support/CMakeLists.txt | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 0c4d7d455b4ca..d550530baa532 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -5619,7 +5619,7 @@ static constexpr int getFEnvRoundingMode(llvm::RoundingMode rm) {
}
APFloat exp(const APFloat &X, RoundingMode rounding_mode) {
- if (&X.getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) {
+ if (&X.getSemantics() == &semIEEEsingle) {
float result = LIBC_NAMESPACE::shared::expf(
X.convertToFloat(), getFEnvRoundingMode(rounding_mode));
return APFloat(result);
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index ca7448a2ece94..118f842a4255f 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -386,6 +386,5 @@ target_include_directories(LLVMSupport
)
# Integrating LLVM libc's math functions
-set_property(TARGET LLVMSupport PROPERTY CXX_STANDARD 17)
target_include_directories(LLVMSupport PRIVATE "${LLVM_INCLUDE_DIR}/../../libc")
target_compile_options(LLVMSupport PRIVATE "-Wno-c99-extensions") # _Complex warnings.
More information about the libc-commits
mailing list