[llvm] Enable logf128 constant folding for hosts with 128bit long double (PR #96287)
Matthew Devereau via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 6 07:52:42 PDT 2024
https://github.com/MDevereau updated https://github.com/llvm/llvm-project/pull/96287
>From 4cc6905d7020140bf1facad3ad9c0888cb7e4734 Mon Sep 17 00:00:00 2001
From: Matt Devereau <matthew.devereau at arm.com>
Date: Fri, 21 Jun 2024 08:34:04 +0000
Subject: [PATCH 1/7] Enable logf128 constant folding for AArch64
AArch64 has a long double bit length of 128. Therefore, it can benefit
from constant fp128 folding. GCC versions more recent than version 12
must use the _Float128 type for logf128.
---
llvm/include/llvm/Support/float128.h | 9 ++++++++-
llvm/lib/Analysis/ConstantFolding.cpp | 4 ++--
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/Support/float128.h b/llvm/include/llvm/Support/float128.h
index e15a98dc5a677..f1931c145f0fc 100644
--- a/llvm/include/llvm/Support/float128.h
+++ b/llvm/include/llvm/Support/float128.h
@@ -11,7 +11,14 @@
namespace llvm {
-#if defined(__clang__) && defined(__FLOAT128__) && \
+#if defined(__aarch64__)
+#define HAS_IEE754_FLOAT128
+#if (defined(__GNUC__) && __GNUC__ > 12)
+typedef _Float128 float128;
+#else
+typedef long double float128;
+#endif
+#elif defined(__clang__) && defined(__FLOAT128__) && \
defined(__SIZEOF_INT128__) && !defined(__LONG_DOUBLE_IBM128__)
#define HAS_IEE754_FLOAT128
typedef __float128 float128;
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 512d1aadd5346..4329d2e9a0556 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1784,8 +1784,8 @@ Constant *ConstantFoldFP(double (*NativeFP)(double), const APFloat &V,
}
#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
-Constant *ConstantFoldFP128(long double (*NativeFP)(long double),
- const APFloat &V, Type *Ty) {
+Constant *ConstantFoldFP128(float128 (*NativeFP)(float128), const APFloat &V,
+ Type *Ty) {
llvm_fenv_clearexcept();
float128 Result = NativeFP(V.convertToQuad());
if (llvm_fenv_testexcept()) {
>From 97a0b2005dc477c491b942933f5ecae7acf187e8 Mon Sep 17 00:00:00 2001
From: Matt Devereau <matthew.devereau at arm.com>
Date: Wed, 26 Jun 2024 13:57:59 +0000
Subject: [PATCH 2/7] Remove aarch64 constraint
Also enable optimisation without cmake opt-in
---
llvm/include/llvm/Support/float128.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Support/float128.h b/llvm/include/llvm/Support/float128.h
index f1931c145f0fc..6068c556ca616 100644
--- a/llvm/include/llvm/Support/float128.h
+++ b/llvm/include/llvm/Support/float128.h
@@ -11,7 +11,8 @@
namespace llvm {
-#if defined(__aarch64__)
+#if !defined(__LONG_DOUBLE_IBM128__) && (__SIZEOF_LONG_DOUBLE__ == 16) && \
+ (__SIZEOF_INT128__ == 16) && (__LDBL_MANT_DIG__ == 113)
#define HAS_IEE754_FLOAT128
#if (defined(__GNUC__) && __GNUC__ > 12)
typedef _Float128 float128;
>From 94c6914a6048c8f044bbe573539f81d7fd9dfecf Mon Sep 17 00:00:00 2001
From: Matt Devereau <matthew.devereau at arm.com>
Date: Wed, 26 Jun 2024 15:08:10 +0000
Subject: [PATCH 3/7] Enable optimization without opt-in
---
llvm/cmake/config-ix.cmake | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake
index 0aae13e30f2ab..7b092917a1bb8 100644
--- a/llvm/cmake/config-ix.cmake
+++ b/llvm/cmake/config-ix.cmake
@@ -247,17 +247,6 @@ else()
set(HAVE_LIBEDIT 0)
endif()
-if(LLVM_HAS_LOGF128)
- include(CheckCXXSymbolExists)
- check_cxx_symbol_exists(logf128 math.h HAS_LOGF128)
-
- if(LLVM_HAS_LOGF128 STREQUAL FORCE_ON AND NOT HAS_LOGF128)
- message(FATAL_ERROR "Failed to configure logf128")
- endif()
-
- set(LLVM_HAS_LOGF128 "${HAS_LOGF128}")
-endif()
-
# function checks
check_symbol_exists(arc4random "stdlib.h" HAVE_DECL_ARC4RANDOM)
find_package(Backtrace)
@@ -271,6 +260,8 @@ if(C_SUPPORTS_WERROR_UNGUARDED_AVAILABILITY_NEW)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror=unguarded-availability-new")
endif()
+check_function_exists(logf128 math.h HAS_LOGF128)
+
# Determine whether we can register EH tables.
check_symbol_exists(__register_frame "${CMAKE_CURRENT_LIST_DIR}/unwind.h" HAVE_REGISTER_FRAME)
check_symbol_exists(__deregister_frame "${CMAKE_CURRENT_LIST_DIR}/unwind.h" HAVE_DEREGISTER_FRAME)
>From 422fed86405852d798d93c59a64d449bc659b056 Mon Sep 17 00:00:00 2001
From: Matt Devereau <matthew.devereau at arm.com>
Date: Thu, 11 Jul 2024 14:30:01 +0000
Subject: [PATCH 4/7] Check for viable logf128 and use that for float128's
typedef
---
llvm/cmake/config-ix.cmake | 58 ++++++++++++++++++++++++++-
llvm/include/llvm/ADT/APFloat.h | 4 +-
llvm/include/llvm/Support/float128.h | 21 ++++------
llvm/lib/Analysis/CMakeLists.txt | 6 ---
llvm/lib/Analysis/ConstantFolding.cpp | 4 +-
llvm/lib/Support/APFloat.cpp | 4 +-
6 files changed, 71 insertions(+), 26 deletions(-)
diff --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake
index 7b092917a1bb8..eb5c3b1008a78 100644
--- a/llvm/cmake/config-ix.cmake
+++ b/llvm/cmake/config-ix.cmake
@@ -260,7 +260,63 @@ if(C_SUPPORTS_WERROR_UNGUARDED_AVAILABILITY_NEW)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror=unguarded-availability-new")
endif()
-check_function_exists(logf128 math.h HAS_LOGF128)
+function(logf128_test testname definition)
+ unset(LOGF128_TEST_RUN CACHE)
+ unset(LOGF128_TEST_COMPILE CACHE)
+ try_run(
+ LOGF128_TEST_RUN
+ LOGF128_TEST_COMPILE
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/logf128_${testname}.cpp
+ LINK_LIBRARIES m
+ )
+ if(LOGF128_TEST_RUN)
+ set (LLVM_HAS_LOGF128 true CACHE INTERNAL "")
+ set(${definition} true CACHE INTERNAL "")
+ message(STATUS "LLVM: found logf128 with type ${testname}")
+ add_compile_definitions(${definition})
+ endif()
+endfunction()
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/logf128_long_double.cpp"
+"
+extern \"C\" {
+long double logf128(long double);
+}
+int main() {
+ long double value = logf128(32.0);
+ if (value > 3.465730L & value < 3.465740L)
+ return 1;
+ return 0;
+}")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/logf128___float128.cpp"
+"
+extern \"C\" {
+__float128 logf128(__float128);
+}
+int main() {
+ __float128 value = logf128(32.0);
+ if (value > 3.465730L & value < 3.465740L)
+ return 1;
+ return 0;
+}")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/logf128__Float128.cpp"
+"
+extern \"C\" {
+_Float128 logf128(_Float128);
+}
+int main() {
+ _Float128 value = logf128(32.0);
+ if (value > 3.465730L & value < 3.465740L)
+ return 1;
+ return 0;
+}")
+
+logf128_test("long_double" HAS_LONG_DOUBLE_LOGF128)
+logf128_test("__float128" HAS__FLOAT128_LOGF128)
+logf128_test("_Float128" HAS_FLOAT128_LOGF128)
# Determine whether we can register EH tables.
check_symbol_exists(__register_frame "${CMAKE_CURRENT_LIST_DIR}/unwind.h" HAVE_REGISTER_FRAME)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index c24eae8da3797..263aa089e10e5 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -370,7 +370,7 @@ class IEEEFloat final : public APFloatBase {
Expected<opStatus> convertFromString(StringRef, roundingMode);
APInt bitcastToAPInt() const;
double convertToDouble() const;
-#ifdef HAS_IEE754_FLOAT128
+#if defined(HAS_IEE754_FLOAT128)
float128 convertToQuad() const;
#endif
float convertToFloat() const;
@@ -1267,7 +1267,7 @@ class APFloat : public APFloatBase {
/// \pre The APFloat must be built using semantics, that can be represented by
/// the host float type without loss of precision. It can be IEEEquad and
/// shorter semantics, like IEEEdouble and others.
-#ifdef HAS_IEE754_FLOAT128
+#if defined(HAS_IEE754_FLOAT128)
float128 convertToQuad() const;
#endif
diff --git a/llvm/include/llvm/Support/float128.h b/llvm/include/llvm/Support/float128.h
index 6068c556ca616..eea11e6ec4e53 100644
--- a/llvm/include/llvm/Support/float128.h
+++ b/llvm/include/llvm/Support/float128.h
@@ -11,23 +11,18 @@
namespace llvm {
-#if !defined(__LONG_DOUBLE_IBM128__) && (__SIZEOF_LONG_DOUBLE__ == 16) && \
- (__SIZEOF_INT128__ == 16) && (__LDBL_MANT_DIG__ == 113)
-#define HAS_IEE754_FLOAT128
-#if (defined(__GNUC__) && __GNUC__ > 12)
+#ifdef HAS_FLOAT128_LOGF128
typedef _Float128 float128;
-#else
-typedef long double float128;
-#endif
-#elif defined(__clang__) && defined(__FLOAT128__) && \
- defined(__SIZEOF_INT128__) && !defined(__LONG_DOUBLE_IBM128__)
#define HAS_IEE754_FLOAT128
+#elif HAS__FLOAT128_LOGF128
typedef __float128 float128;
-#elif defined(__FLOAT128__) && defined(__SIZEOF_INT128__) && \
- !defined(__LONG_DOUBLE_IBM128__) && \
- (defined(__GNUC__) || defined(__GNUG__))
+extern "C" {
+float128 logf128(float128);
+}
+#define HAS_IEE754_FLOAT128
+#elif HAS_LONG_DOUBLE_LOGF128
+typedef long double float128;
#define HAS_IEE754_FLOAT128
-typedef _Float128 float128;
#endif
} // namespace llvm
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index 74476cb5440c6..474b8d20fde16 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -159,9 +159,3 @@ add_llvm_component_library(LLVMAnalysis
Support
TargetParser
)
-
-include(CheckCXXSymbolExists)
-check_cxx_symbol_exists(logf128 math.h HAS_LOGF128)
-if(HAS_LOGF128)
- target_compile_definitions(LLVMAnalysis PRIVATE HAS_LOGF128)
-endif()
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 4329d2e9a0556..2ec6e909ea242 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1783,7 +1783,7 @@ Constant *ConstantFoldFP(double (*NativeFP)(double), const APFloat &V,
return GetConstantFoldFPValue(Result, Ty);
}
-#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
+#if defined(HAS_IEE754_FLOAT128)
Constant *ConstantFoldFP128(float128 (*NativeFP)(float128), const APFloat &V,
Type *Ty) {
llvm_fenv_clearexcept();
@@ -2116,7 +2116,7 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
if (IntrinsicID == Intrinsic::canonicalize)
return constantFoldCanonicalize(Ty, Call, U);
-#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
+#if defined(HAS_IEE754_FLOAT128)
if (Ty->isFP128Ty()) {
if (IntrinsicID == Intrinsic::log) {
float128 Result = logf128(Op->getValueAPF().convertToQuad());
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 47618bc325951..2c46e43173ae2 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -3721,7 +3721,7 @@ double IEEEFloat::convertToDouble() const {
return api.bitsToDouble();
}
-#ifdef HAS_IEE754_FLOAT128
+#if defined(HAS_IEE754_FLOAT128)
float128 IEEEFloat::convertToQuad() const {
assert(semantics == (const llvm::fltSemantics *)&semIEEEquad &&
"Float semantics are not IEEEquads");
@@ -5351,7 +5351,7 @@ double APFloat::convertToDouble() const {
return Temp.getIEEE().convertToDouble();
}
-#ifdef HAS_IEE754_FLOAT128
+#if defined(HAS_IEE754_FLOAT128)
float128 APFloat::convertToQuad() const {
if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEquad)
return getIEEE().convertToQuad();
>From 613f6a4b316753bcc885ec5a7f3628497a474b12 Mon Sep 17 00:00:00 2001
From: Matt Devereau <matthew.devereau at arm.com>
Date: Wed, 17 Jul 2024 13:52:42 +0000
Subject: [PATCH 5/7] Remove cmake tests
---
llvm/cmake/config-ix.cmake | 61 ++--------------------------
llvm/include/llvm/Support/float128.h | 18 ++++----
2 files changed, 11 insertions(+), 68 deletions(-)
diff --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake
index eb5c3b1008a78..f7ba1a827b4af 100644
--- a/llvm/cmake/config-ix.cmake
+++ b/llvm/cmake/config-ix.cmake
@@ -260,63 +260,10 @@ if(C_SUPPORTS_WERROR_UNGUARDED_AVAILABILITY_NEW)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror=unguarded-availability-new")
endif()
-function(logf128_test testname definition)
- unset(LOGF128_TEST_RUN CACHE)
- unset(LOGF128_TEST_COMPILE CACHE)
- try_run(
- LOGF128_TEST_RUN
- LOGF128_TEST_COMPILE
- ${CMAKE_CURRENT_BINARY_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}/logf128_${testname}.cpp
- LINK_LIBRARIES m
- )
- if(LOGF128_TEST_RUN)
- set (LLVM_HAS_LOGF128 true CACHE INTERNAL "")
- set(${definition} true CACHE INTERNAL "")
- message(STATUS "LLVM: found logf128 with type ${testname}")
- add_compile_definitions(${definition})
- endif()
-endfunction()
-
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/logf128_long_double.cpp"
-"
-extern \"C\" {
-long double logf128(long double);
-}
-int main() {
- long double value = logf128(32.0);
- if (value > 3.465730L & value < 3.465740L)
- return 1;
- return 0;
-}")
-
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/logf128___float128.cpp"
-"
-extern \"C\" {
-__float128 logf128(__float128);
-}
-int main() {
- __float128 value = logf128(32.0);
- if (value > 3.465730L & value < 3.465740L)
- return 1;
- return 0;
-}")
-
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/logf128__Float128.cpp"
-"
-extern \"C\" {
-_Float128 logf128(_Float128);
-}
-int main() {
- _Float128 value = logf128(32.0);
- if (value > 3.465730L & value < 3.465740L)
- return 1;
- return 0;
-}")
-
-logf128_test("long_double" HAS_LONG_DOUBLE_LOGF128)
-logf128_test("__float128" HAS__FLOAT128_LOGF128)
-logf128_test("_Float128" HAS_FLOAT128_LOGF128)
+check_cxx_symbol_exists(logf128 cmath HAS_LOGF128)
+if(HAS_LOGF128)
+ add_compile_definitions(HAS_LOGF128)
+endif()
# Determine whether we can register EH tables.
check_symbol_exists(__register_frame "${CMAKE_CURRENT_LIST_DIR}/unwind.h" HAVE_REGISTER_FRAME)
diff --git a/llvm/include/llvm/Support/float128.h b/llvm/include/llvm/Support/float128.h
index eea11e6ec4e53..45dc5cb8bc0f4 100644
--- a/llvm/include/llvm/Support/float128.h
+++ b/llvm/include/llvm/Support/float128.h
@@ -9,21 +9,17 @@
#ifndef LLVM_FLOAT128
#define LLVM_FLOAT128
+#include <cmath>
+
namespace llvm {
-#ifdef HAS_FLOAT128_LOGF128
-typedef _Float128 float128;
-#define HAS_IEE754_FLOAT128
-#elif HAS__FLOAT128_LOGF128
-typedef __float128 float128;
-extern "C" {
-float128 logf128(float128);
-}
-#define HAS_IEE754_FLOAT128
-#elif HAS_LONG_DOUBLE_LOGF128
-typedef long double float128;
+#ifdef HAS_LOGF128
+#if (__LDBL_MANT_DIG__ == 113) && !defined(__LONG_DOUBLE_IBM128__) && \
+ (__SIZEOF_INT128__ == 16)
+typedef decltype(logf128(0.)) float128;
#define HAS_IEE754_FLOAT128
#endif
+#endif // HAS_LOGF128
} // namespace llvm
#endif // LLVM_FLOAT128
>From 57053167e044b509d4765d0caa00f64083588b90 Mon Sep 17 00:00:00 2001
From: Matt Devereau <matthew.devereau at arm.com>
Date: Thu, 18 Jul 2024 10:32:51 +0000
Subject: [PATCH 6/7] Lit uses LLVM_HAS_LOGF128 to run tests and is no longer a
command line option
---
llvm/CMakeLists.txt | 2 --
llvm/cmake/config-ix.cmake | 1 +
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 3208147101c0d..08e8f69cee4d2 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -560,8 +560,6 @@ set(LLVM_USE_STATIC_ZSTD FALSE CACHE BOOL "Use static version of zstd. Can be TR
set(LLVM_ENABLE_CURL "OFF" CACHE STRING "Use libcurl for the HTTP client if available. Can be ON, OFF, or FORCE_ON")
-set(LLVM_HAS_LOGF128 "OFF" CACHE STRING "Use logf128 to constant fold fp128 logarithm calls. Can be ON, OFF, or FORCE_ON")
-
set(LLVM_ENABLE_HTTPLIB "OFF" CACHE STRING "Use cpp-httplib HTTP server library if available. Can be ON, OFF, or FORCE_ON")
set(LLVM_Z3_INSTALL_DIR "" CACHE STRING "Install directory of the Z3 solver.")
diff --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake
index f7ba1a827b4af..5e8c7c73a690d 100644
--- a/llvm/cmake/config-ix.cmake
+++ b/llvm/cmake/config-ix.cmake
@@ -262,6 +262,7 @@ endif()
check_cxx_symbol_exists(logf128 cmath HAS_LOGF128)
if(HAS_LOGF128)
+ set(LLVM_HAS_LOGF128 On)
add_compile_definitions(HAS_LOGF128)
endif()
>From 6ceda722a73b47761023837f0e0bbc3495ef5e1d Mon Sep 17 00:00:00 2001
From: Matt Devereau <matthew.devereau at arm.com>
Date: Tue, 6 Aug 2024 14:51:06 +0000
Subject: [PATCH 7/7] Remove check for __LDBL_MANT_DIG__
---
llvm/include/llvm/Support/float128.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/include/llvm/Support/float128.h b/llvm/include/llvm/Support/float128.h
index 45dc5cb8bc0f4..618b320086ba5 100644
--- a/llvm/include/llvm/Support/float128.h
+++ b/llvm/include/llvm/Support/float128.h
@@ -14,8 +14,7 @@
namespace llvm {
#ifdef HAS_LOGF128
-#if (__LDBL_MANT_DIG__ == 113) && !defined(__LONG_DOUBLE_IBM128__) && \
- (__SIZEOF_INT128__ == 16)
+#if !defined(__LONG_DOUBLE_IBM128__) && (__SIZEOF_INT128__ == 16)
typedef decltype(logf128(0.)) float128;
#define HAS_IEE754_FLOAT128
#endif
More information about the llvm-commits
mailing list