Skip to content

Enable logf128 constant folding for hosts with 128bit long double #106563

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

Closed
wants to merge 1 commit into from

Conversation

MDevereau
Copy link
Contributor

Hosts with a long double size of 128 bits can benefit highly from constant fp128 folding with the function logf128

This patch relands #104929. With commits 001e423 and 83a5c7c fixing buildbot failures.

This patch also adds the option to manually disable the behaviour with the cmake option -DLLVM_DISABLE_LOGF128=On

Hosts with a long double size of 128 bits can benefit highly
from constant fp128 folding with the function logf128

This patch relands llvm#104929. With commits 001e423 and 83a5c7c
fixing buildbot failures.

This patch also adds the option to manually disable the behaviour
with the cmake option -DLLVM_DISABLE_LOGF128=On
@llvmbot llvmbot added cmake Build system in general and CMake in particular llvm:support bazel "Peripheral" support tier build system: utils/bazel llvm:analysis llvm:transforms llvm:adt labels Aug 29, 2024
@llvmbot
Copy link
Member

llvmbot commented Aug 29, 2024

@llvm/pr-subscribers-llvm-adt
@llvm/pr-subscribers-llvm-analysis

@llvm/pr-subscribers-llvm-transforms

Author: Matthew Devereau (MDevereau)

Changes

Hosts with a long double size of 128 bits can benefit highly from constant fp128 folding with the function logf128

This patch relands #104929. With commits 001e423 and 83a5c7c fixing buildbot failures.

This patch also adds the option to manually disable the behaviour with the cmake option -DLLVM_DISABLE_LOGF128=On


Full diff: https://github.com/llvm/llvm-project/pull/106563.diff

16 Files Affected:

  • (modified) llvm/CMakeLists.txt (+1-1)
  • (modified) llvm/cmake/config-ix.cmake (+6-11)
  • (modified) llvm/include/llvm/ADT/APFloat.h (+3-12)
  • (modified) llvm/include/llvm/ADT/APInt.h (-8)
  • (modified) llvm/include/llvm/Config/llvm-config.h.cmake (+2-2)
  • (modified) llvm/include/llvm/Support/float128.h (+6-8)
  • (modified) llvm/lib/Analysis/CMakeLists.txt (-4)
  • (modified) llvm/lib/Analysis/ConstantFolding.cpp (+24-5)
  • (modified) llvm/lib/Support/APFloat.cpp (+2-22)
  • (modified) llvm/test/CMakeLists.txt (+1-1)
  • (modified) llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll (+1-1)
  • (modified) llvm/test/lit.cfg.py (+2-2)
  • (modified) llvm/test/lit.site.cfg.py.in (+1-1)
  • (modified) llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn (+1-1)
  • (modified) llvm/utils/gn/secondary/llvm/test/BUILD.gn (+1-1)
  • (modified) utils/bazel/llvm_configs/llvm-config.h.cmake (+2-2)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index d681b1ccab6299..b5a9096f8bd48f 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -560,7 +560,7 @@ 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_DISABLE_LOGF128 "OFF" CACHE BOOL "Disable the use of 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")
 
diff --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake
index f76eacb9d51366..078cc9f7d48bf8 100644
--- a/llvm/cmake/config-ix.cmake
+++ b/llvm/cmake/config-ix.cmake
@@ -246,17 +246,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)
@@ -270,6 +259,12 @@ if(C_SUPPORTS_WERROR_UNGUARDED_AVAILABILITY_NEW)
   set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror=unguarded-availability-new")
 endif()
 
+check_cxx_symbol_exists(logf128 cmath HAS_LOGF128)
+check_symbol_exists(__powerpc__ "" __PPC)
+if(HAS_LOGF128 AND NOT __PPC AND NOT LLVM_DISABLE_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)
 check_symbol_exists(__deregister_frame "${CMAKE_CURRENT_LIST_DIR}/unwind.h" HAVE_DEREGISTER_FRAME)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index 7039e961bff82d..925d03d4c06670 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -19,7 +19,6 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/FloatingPointMode.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/float128.h"
 #include <memory>
 
 #define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL)                             \
@@ -378,9 +377,6 @@ class IEEEFloat final : public APFloatBase {
   Expected<opStatus> convertFromString(StringRef, roundingMode);
   APInt bitcastToAPInt() const;
   double convertToDouble() const;
-#ifdef HAS_IEE754_FLOAT128
-  float128 convertToQuad() const;
-#endif
   float convertToFloat() const;
 
   /// @}
@@ -1274,14 +1270,9 @@ class APFloat : public APFloatBase {
   /// shorter semantics, like IEEEsingle and others.
   double convertToDouble() const;
 
-  /// Converts this APFloat to host float value.
-  ///
-  /// \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
-  float128 convertToQuad() const;
-#endif
+  /// Return true if this APFloat has quadruple precision floating point
+  /// semantics
+  bool isValidIEEEQuad() const;
 
   /// Converts this APFloat to host float value.
   ///
diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index 65ba3f15305c78..13837413ae49fe 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -17,7 +17,6 @@
 
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/MathExtras.h"
-#include "llvm/Support/float128.h"
 #include <cassert>
 #include <climits>
 #include <cstring>
@@ -1677,13 +1676,6 @@ class [[nodiscard]] APInt {
   /// any bit width. Exactly 64 bits will be translated.
   double bitsToDouble() const { return llvm::bit_cast<double>(getWord(0)); }
 
-#ifdef HAS_IEE754_FLOAT128
-  float128 bitsToQuad() const {
-    __uint128_t ul = ((__uint128_t)U.pVal[1] << 64) + U.pVal[0];
-    return llvm::bit_cast<float128>(ul);
-  }
-#endif
-
   /// Converts APInt bits to a float
   ///
   /// The conversion does not do a translation from integer to float, it just
diff --git a/llvm/include/llvm/Config/llvm-config.h.cmake b/llvm/include/llvm/Config/llvm-config.h.cmake
index 629977cc11d683..87e6a4c075ca10 100644
--- a/llvm/include/llvm/Config/llvm-config.h.cmake
+++ b/llvm/include/llvm/Config/llvm-config.h.cmake
@@ -198,7 +198,7 @@
 /* Define if plugins enabled */
 #cmakedefine LLVM_ENABLE_PLUGINS
 
-/* Define if logf128 is available */
-#cmakedefine LLVM_HAS_LOGF128
+/* Define if logf128 is disabled */
+#cmakedefine LLVM_DISABLE_LOGF128
 
 #endif
diff --git a/llvm/include/llvm/Support/float128.h b/llvm/include/llvm/Support/float128.h
index e15a98dc5a6779..618b320086ba59 100644
--- a/llvm/include/llvm/Support/float128.h
+++ b/llvm/include/llvm/Support/float128.h
@@ -9,18 +9,16 @@
 #ifndef LLVM_FLOAT128
 #define LLVM_FLOAT128
 
+#include <cmath>
+
 namespace llvm {
 
-#if defined(__clang__) && defined(__FLOAT128__) &&                             \
-    defined(__SIZEOF_INT128__) && !defined(__LONG_DOUBLE_IBM128__)
-#define HAS_IEE754_FLOAT128
-typedef __float128 float128;
-#elif defined(__FLOAT128__) && defined(__SIZEOF_INT128__) &&                   \
-    !defined(__LONG_DOUBLE_IBM128__) &&                                        \
-    (defined(__GNUC__) || defined(__GNUG__))
+#ifdef HAS_LOGF128
+#if !defined(__LONG_DOUBLE_IBM128__) && (__SIZEOF_INT128__ == 16)
+typedef decltype(logf128(0.)) float128;
 #define HAS_IEE754_FLOAT128
-typedef _Float128 float128;
 #endif
+#endif // HAS_LOGF128
 
 } // namespace llvm
 #endif // LLVM_FLOAT128
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index 99ce0acdabe1ba..3127f45cc54cb1 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -162,7 +162,3 @@ add_llvm_component_library(LLVMAnalysis
   Support
   TargetParser
   )
-
-if(LLVM_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 a7a6de3f3b97b0..469c5ac17602bb 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -54,6 +54,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/KnownBits.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Support/float128.h"
 #include <cassert>
 #include <cerrno>
 #include <cfenv>
@@ -1741,7 +1742,7 @@ Constant *GetConstantFoldFPValue(double V, Type *Ty) {
   llvm_unreachable("Can only constant fold half/float/double");
 }
 
-#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
+#if defined(HAS_IEE754_FLOAT128)
 Constant *GetConstantFoldFPValue128(float128 V, Type *Ty) {
   if (Ty->isFP128Ty())
     return ConstantFP::get(Ty, V);
@@ -1781,11 +1782,25 @@ 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)
+float128 ConvertToQuad(const APFloat &Apf) {
+  APInt Api = Apf.bitcastToAPInt();
+  __uint128_t Uint128 =
+      ((__uint128_t)Api.extractBitsAsZExtValue(64, 64) << 64) +
+      Api.extractBitsAsZExtValue(64, 0);
+  return llvm::bit_cast<float128>(Uint128);
+}
+#endif
+
+#if defined(HAS_IEE754_FLOAT128)
 Constant *ConstantFoldFP128(float128 (*NativeFP)(float128), const APFloat &V,
                             Type *Ty) {
   llvm_fenv_clearexcept();
-  float128 Result = NativeFP(V.convertToQuad());
+  if (!V.isValidIEEEQuad())
+    return nullptr;
+
+  float128 Result = NativeFP(ConvertToQuad(V));
+
   if (llvm_fenv_testexcept()) {
     llvm_fenv_clearexcept();
     return nullptr;
@@ -2114,10 +2129,14 @@ 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());
+        APFloat Value = Op->getValueAPF();
+        if (!Value.isValidIEEEQuad())
+          return nullptr;
+
+        float128 Result = logf128(ConvertToQuad(Value));
         return GetConstantFoldFPValue128(Result, Ty);
       }
 
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 7f68c5ab9b7cf7..2ddf99f56f88d5 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -3749,15 +3749,6 @@ double IEEEFloat::convertToDouble() const {
   return api.bitsToDouble();
 }
 
-#ifdef HAS_IEE754_FLOAT128
-float128 IEEEFloat::convertToQuad() const {
-  assert(semantics == (const llvm::fltSemantics *)&semIEEEquad &&
-         "Float semantics are not IEEEquads");
-  APInt api = bitcastToAPInt();
-  return api.bitsToQuad();
-}
-#endif
-
 /// Integer bit is explicit in this format.  Intel hardware (387 and later)
 /// does not support these bit patterns:
 ///  exponent = all 1's, integer bit 0, significand 0 ("pseudoinfinity")
@@ -5406,20 +5397,9 @@ double APFloat::convertToDouble() const {
   return Temp.getIEEE().convertToDouble();
 }
 
-#ifdef HAS_IEE754_FLOAT128
-float128 APFloat::convertToQuad() const {
-  if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEquad)
-    return getIEEE().convertToQuad();
-  assert(getSemantics().isRepresentableBy(semIEEEquad) &&
-         "Float semantics is not representable by IEEEquad");
-  APFloat Temp = *this;
-  bool LosesInfo;
-  opStatus St = Temp.convert(semIEEEquad, rmNearestTiesToEven, &LosesInfo);
-  assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision");
-  (void)St;
-  return Temp.getIEEE().convertToQuad();
+bool APFloat::isValidIEEEQuad() const {
+  return (&getSemantics() == (const llvm::fltSemantics *)&semIEEEquad);
 }
-#endif
 
 float APFloat::convertToFloat() const {
   if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle)
diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt
index 0f449fa2d45be9..423884c8d92148 100644
--- a/llvm/test/CMakeLists.txt
+++ b/llvm/test/CMakeLists.txt
@@ -26,7 +26,7 @@ llvm_canonicalize_cmake_booleans(
   LLVM_TOOL_LLVM_DRIVER_BUILD
   LLVM_INCLUDE_SPIRV_TOOLS_TESTS
   LLVM_APPEND_VC_REV
-  LLVM_HAS_LOGF128
+  LLVM_DISABLE_LOGF128
   )
 
 configure_lit_site_cfg(
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll b/llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll
index 82db5e4066cb1b..d4b569911e58a6 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
 
-; REQUIRES: has_logf128
+; UNSUPPORTED: disable_logf128
 declare fp128 @llvm.log.f128(fp128)
 declare fp128 @logl(fp128)
 
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index bee7aa3903a1f5..58a40ca9322732 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -620,5 +620,5 @@ def have_ld64_plugin_support():
 if "system-aix" in config.available_features:
     config.environment["OBJECT_MODE"] = "any"
 
-if config.has_logf128:
-    config.available_features.add("has_logf128")
+if config.disable_logf128:
+    config.available_features.add("disable_logf128")
diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in
index 0968f6214772d0..185db7b4a71ac2 100644
--- a/llvm/test/lit.site.cfg.py.in
+++ b/llvm/test/lit.site.cfg.py.in
@@ -63,7 +63,7 @@ config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@
 config.spirv_tools_tests = @LLVM_INCLUDE_SPIRV_TOOLS_TESTS@
 config.have_vc_rev = @LLVM_APPEND_VC_REV@
 config.force_vc_rev = "@LLVM_FORCE_VC_REVISION@"
-config.has_logf128 = @LLVM_HAS_LOGF128@
+config.disable_logf128 = @LLVM_DISABLE_LOGF128@
 
 import lit.llvm
 lit.llvm.initialize(lit_config, config)
diff --git a/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn b/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
index 1c9c19241508a7..079900e0b96347 100644
--- a/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
@@ -316,7 +316,7 @@ write_cmake_config("llvm-config") {
     "LLVM_ENABLE_HTTPLIB=",
     "LLVM_FORCE_USE_OLD_TOOLCHAIN=",
     "LLVM_HAS_ATOMICS=1",
-    "LLVM_HAS_LOGF128=",
+    "LLVM_DISABLE_LOGF128=",
     "LLVM_HAVE_TFLITE=",
     "LLVM_HOST_TRIPLE=$llvm_current_triple",
     "LLVM_NATIVE_ARCH=$native_target",
diff --git a/llvm/utils/gn/secondary/llvm/test/BUILD.gn b/llvm/utils/gn/secondary/llvm/test/BUILD.gn
index 33beb0516aba2a..b9b2ad32eb9e0a 100644
--- a/llvm/utils/gn/secondary/llvm/test/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/test/BUILD.gn
@@ -64,7 +64,7 @@ write_lit_config("lit_site_cfg") {
     "LLVM_ENABLE_FFI=0",
     "LLVM_ENABLE_HTTPLIB=0",
     "LLVM_FORCE_VC_REVISION=",
-    "LLVM_HAS_LOGF128=0",
+    "LLVM_DISABLE_LOGF128=0",
     "LLVM_HAVE_OPT_VIEWER_MODULES=0",
     "LLVM_HOST_TRIPLE=$llvm_current_triple",
     "LLVM_INCLUDE_DXIL_TESTS=0",
diff --git a/utils/bazel/llvm_configs/llvm-config.h.cmake b/utils/bazel/llvm_configs/llvm-config.h.cmake
index 629977cc11d683..87e6a4c075ca10 100644
--- a/utils/bazel/llvm_configs/llvm-config.h.cmake
+++ b/utils/bazel/llvm_configs/llvm-config.h.cmake
@@ -198,7 +198,7 @@
 /* Define if plugins enabled */
 #cmakedefine LLVM_ENABLE_PLUGINS
 
-/* Define if logf128 is available */
-#cmakedefine LLVM_HAS_LOGF128
+/* Define if logf128 is disabled */
+#cmakedefine LLVM_DISABLE_LOGF128
 
 #endif

@llvmbot
Copy link
Member

llvmbot commented Aug 29, 2024

@llvm/pr-subscribers-llvm-support

Author: Matthew Devereau (MDevereau)

Changes

Hosts with a long double size of 128 bits can benefit highly from constant fp128 folding with the function logf128

This patch relands #104929. With commits 001e423 and 83a5c7c fixing buildbot failures.

This patch also adds the option to manually disable the behaviour with the cmake option -DLLVM_DISABLE_LOGF128=On


Full diff: https://github.com/llvm/llvm-project/pull/106563.diff

16 Files Affected:

  • (modified) llvm/CMakeLists.txt (+1-1)
  • (modified) llvm/cmake/config-ix.cmake (+6-11)
  • (modified) llvm/include/llvm/ADT/APFloat.h (+3-12)
  • (modified) llvm/include/llvm/ADT/APInt.h (-8)
  • (modified) llvm/include/llvm/Config/llvm-config.h.cmake (+2-2)
  • (modified) llvm/include/llvm/Support/float128.h (+6-8)
  • (modified) llvm/lib/Analysis/CMakeLists.txt (-4)
  • (modified) llvm/lib/Analysis/ConstantFolding.cpp (+24-5)
  • (modified) llvm/lib/Support/APFloat.cpp (+2-22)
  • (modified) llvm/test/CMakeLists.txt (+1-1)
  • (modified) llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll (+1-1)
  • (modified) llvm/test/lit.cfg.py (+2-2)
  • (modified) llvm/test/lit.site.cfg.py.in (+1-1)
  • (modified) llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn (+1-1)
  • (modified) llvm/utils/gn/secondary/llvm/test/BUILD.gn (+1-1)
  • (modified) utils/bazel/llvm_configs/llvm-config.h.cmake (+2-2)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index d681b1ccab6299..b5a9096f8bd48f 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -560,7 +560,7 @@ 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_DISABLE_LOGF128 "OFF" CACHE BOOL "Disable the use of 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")
 
diff --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake
index f76eacb9d51366..078cc9f7d48bf8 100644
--- a/llvm/cmake/config-ix.cmake
+++ b/llvm/cmake/config-ix.cmake
@@ -246,17 +246,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)
@@ -270,6 +259,12 @@ if(C_SUPPORTS_WERROR_UNGUARDED_AVAILABILITY_NEW)
   set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror=unguarded-availability-new")
 endif()
 
+check_cxx_symbol_exists(logf128 cmath HAS_LOGF128)
+check_symbol_exists(__powerpc__ "" __PPC)
+if(HAS_LOGF128 AND NOT __PPC AND NOT LLVM_DISABLE_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)
 check_symbol_exists(__deregister_frame "${CMAKE_CURRENT_LIST_DIR}/unwind.h" HAVE_DEREGISTER_FRAME)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index 7039e961bff82d..925d03d4c06670 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -19,7 +19,6 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/FloatingPointMode.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/float128.h"
 #include <memory>
 
 #define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL)                             \
@@ -378,9 +377,6 @@ class IEEEFloat final : public APFloatBase {
   Expected<opStatus> convertFromString(StringRef, roundingMode);
   APInt bitcastToAPInt() const;
   double convertToDouble() const;
-#ifdef HAS_IEE754_FLOAT128
-  float128 convertToQuad() const;
-#endif
   float convertToFloat() const;
 
   /// @}
@@ -1274,14 +1270,9 @@ class APFloat : public APFloatBase {
   /// shorter semantics, like IEEEsingle and others.
   double convertToDouble() const;
 
-  /// Converts this APFloat to host float value.
-  ///
-  /// \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
-  float128 convertToQuad() const;
-#endif
+  /// Return true if this APFloat has quadruple precision floating point
+  /// semantics
+  bool isValidIEEEQuad() const;
 
   /// Converts this APFloat to host float value.
   ///
diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index 65ba3f15305c78..13837413ae49fe 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -17,7 +17,6 @@
 
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/MathExtras.h"
-#include "llvm/Support/float128.h"
 #include <cassert>
 #include <climits>
 #include <cstring>
@@ -1677,13 +1676,6 @@ class [[nodiscard]] APInt {
   /// any bit width. Exactly 64 bits will be translated.
   double bitsToDouble() const { return llvm::bit_cast<double>(getWord(0)); }
 
-#ifdef HAS_IEE754_FLOAT128
-  float128 bitsToQuad() const {
-    __uint128_t ul = ((__uint128_t)U.pVal[1] << 64) + U.pVal[0];
-    return llvm::bit_cast<float128>(ul);
-  }
-#endif
-
   /// Converts APInt bits to a float
   ///
   /// The conversion does not do a translation from integer to float, it just
diff --git a/llvm/include/llvm/Config/llvm-config.h.cmake b/llvm/include/llvm/Config/llvm-config.h.cmake
index 629977cc11d683..87e6a4c075ca10 100644
--- a/llvm/include/llvm/Config/llvm-config.h.cmake
+++ b/llvm/include/llvm/Config/llvm-config.h.cmake
@@ -198,7 +198,7 @@
 /* Define if plugins enabled */
 #cmakedefine LLVM_ENABLE_PLUGINS
 
-/* Define if logf128 is available */
-#cmakedefine LLVM_HAS_LOGF128
+/* Define if logf128 is disabled */
+#cmakedefine LLVM_DISABLE_LOGF128
 
 #endif
diff --git a/llvm/include/llvm/Support/float128.h b/llvm/include/llvm/Support/float128.h
index e15a98dc5a6779..618b320086ba59 100644
--- a/llvm/include/llvm/Support/float128.h
+++ b/llvm/include/llvm/Support/float128.h
@@ -9,18 +9,16 @@
 #ifndef LLVM_FLOAT128
 #define LLVM_FLOAT128
 
+#include <cmath>
+
 namespace llvm {
 
-#if defined(__clang__) && defined(__FLOAT128__) &&                             \
-    defined(__SIZEOF_INT128__) && !defined(__LONG_DOUBLE_IBM128__)
-#define HAS_IEE754_FLOAT128
-typedef __float128 float128;
-#elif defined(__FLOAT128__) && defined(__SIZEOF_INT128__) &&                   \
-    !defined(__LONG_DOUBLE_IBM128__) &&                                        \
-    (defined(__GNUC__) || defined(__GNUG__))
+#ifdef HAS_LOGF128
+#if !defined(__LONG_DOUBLE_IBM128__) && (__SIZEOF_INT128__ == 16)
+typedef decltype(logf128(0.)) float128;
 #define HAS_IEE754_FLOAT128
-typedef _Float128 float128;
 #endif
+#endif // HAS_LOGF128
 
 } // namespace llvm
 #endif // LLVM_FLOAT128
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index 99ce0acdabe1ba..3127f45cc54cb1 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -162,7 +162,3 @@ add_llvm_component_library(LLVMAnalysis
   Support
   TargetParser
   )
-
-if(LLVM_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 a7a6de3f3b97b0..469c5ac17602bb 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -54,6 +54,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/KnownBits.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Support/float128.h"
 #include <cassert>
 #include <cerrno>
 #include <cfenv>
@@ -1741,7 +1742,7 @@ Constant *GetConstantFoldFPValue(double V, Type *Ty) {
   llvm_unreachable("Can only constant fold half/float/double");
 }
 
-#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
+#if defined(HAS_IEE754_FLOAT128)
 Constant *GetConstantFoldFPValue128(float128 V, Type *Ty) {
   if (Ty->isFP128Ty())
     return ConstantFP::get(Ty, V);
@@ -1781,11 +1782,25 @@ 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)
+float128 ConvertToQuad(const APFloat &Apf) {
+  APInt Api = Apf.bitcastToAPInt();
+  __uint128_t Uint128 =
+      ((__uint128_t)Api.extractBitsAsZExtValue(64, 64) << 64) +
+      Api.extractBitsAsZExtValue(64, 0);
+  return llvm::bit_cast<float128>(Uint128);
+}
+#endif
+
+#if defined(HAS_IEE754_FLOAT128)
 Constant *ConstantFoldFP128(float128 (*NativeFP)(float128), const APFloat &V,
                             Type *Ty) {
   llvm_fenv_clearexcept();
-  float128 Result = NativeFP(V.convertToQuad());
+  if (!V.isValidIEEEQuad())
+    return nullptr;
+
+  float128 Result = NativeFP(ConvertToQuad(V));
+
   if (llvm_fenv_testexcept()) {
     llvm_fenv_clearexcept();
     return nullptr;
@@ -2114,10 +2129,14 @@ 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());
+        APFloat Value = Op->getValueAPF();
+        if (!Value.isValidIEEEQuad())
+          return nullptr;
+
+        float128 Result = logf128(ConvertToQuad(Value));
         return GetConstantFoldFPValue128(Result, Ty);
       }
 
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 7f68c5ab9b7cf7..2ddf99f56f88d5 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -3749,15 +3749,6 @@ double IEEEFloat::convertToDouble() const {
   return api.bitsToDouble();
 }
 
-#ifdef HAS_IEE754_FLOAT128
-float128 IEEEFloat::convertToQuad() const {
-  assert(semantics == (const llvm::fltSemantics *)&semIEEEquad &&
-         "Float semantics are not IEEEquads");
-  APInt api = bitcastToAPInt();
-  return api.bitsToQuad();
-}
-#endif
-
 /// Integer bit is explicit in this format.  Intel hardware (387 and later)
 /// does not support these bit patterns:
 ///  exponent = all 1's, integer bit 0, significand 0 ("pseudoinfinity")
@@ -5406,20 +5397,9 @@ double APFloat::convertToDouble() const {
   return Temp.getIEEE().convertToDouble();
 }
 
-#ifdef HAS_IEE754_FLOAT128
-float128 APFloat::convertToQuad() const {
-  if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEquad)
-    return getIEEE().convertToQuad();
-  assert(getSemantics().isRepresentableBy(semIEEEquad) &&
-         "Float semantics is not representable by IEEEquad");
-  APFloat Temp = *this;
-  bool LosesInfo;
-  opStatus St = Temp.convert(semIEEEquad, rmNearestTiesToEven, &LosesInfo);
-  assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision");
-  (void)St;
-  return Temp.getIEEE().convertToQuad();
+bool APFloat::isValidIEEEQuad() const {
+  return (&getSemantics() == (const llvm::fltSemantics *)&semIEEEquad);
 }
-#endif
 
 float APFloat::convertToFloat() const {
   if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle)
diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt
index 0f449fa2d45be9..423884c8d92148 100644
--- a/llvm/test/CMakeLists.txt
+++ b/llvm/test/CMakeLists.txt
@@ -26,7 +26,7 @@ llvm_canonicalize_cmake_booleans(
   LLVM_TOOL_LLVM_DRIVER_BUILD
   LLVM_INCLUDE_SPIRV_TOOLS_TESTS
   LLVM_APPEND_VC_REV
-  LLVM_HAS_LOGF128
+  LLVM_DISABLE_LOGF128
   )
 
 configure_lit_site_cfg(
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll b/llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll
index 82db5e4066cb1b..d4b569911e58a6 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
 
-; REQUIRES: has_logf128
+; UNSUPPORTED: disable_logf128
 declare fp128 @llvm.log.f128(fp128)
 declare fp128 @logl(fp128)
 
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index bee7aa3903a1f5..58a40ca9322732 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -620,5 +620,5 @@ def have_ld64_plugin_support():
 if "system-aix" in config.available_features:
     config.environment["OBJECT_MODE"] = "any"
 
-if config.has_logf128:
-    config.available_features.add("has_logf128")
+if config.disable_logf128:
+    config.available_features.add("disable_logf128")
diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in
index 0968f6214772d0..185db7b4a71ac2 100644
--- a/llvm/test/lit.site.cfg.py.in
+++ b/llvm/test/lit.site.cfg.py.in
@@ -63,7 +63,7 @@ config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@
 config.spirv_tools_tests = @LLVM_INCLUDE_SPIRV_TOOLS_TESTS@
 config.have_vc_rev = @LLVM_APPEND_VC_REV@
 config.force_vc_rev = "@LLVM_FORCE_VC_REVISION@"
-config.has_logf128 = @LLVM_HAS_LOGF128@
+config.disable_logf128 = @LLVM_DISABLE_LOGF128@
 
 import lit.llvm
 lit.llvm.initialize(lit_config, config)
diff --git a/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn b/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
index 1c9c19241508a7..079900e0b96347 100644
--- a/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
@@ -316,7 +316,7 @@ write_cmake_config("llvm-config") {
     "LLVM_ENABLE_HTTPLIB=",
     "LLVM_FORCE_USE_OLD_TOOLCHAIN=",
     "LLVM_HAS_ATOMICS=1",
-    "LLVM_HAS_LOGF128=",
+    "LLVM_DISABLE_LOGF128=",
     "LLVM_HAVE_TFLITE=",
     "LLVM_HOST_TRIPLE=$llvm_current_triple",
     "LLVM_NATIVE_ARCH=$native_target",
diff --git a/llvm/utils/gn/secondary/llvm/test/BUILD.gn b/llvm/utils/gn/secondary/llvm/test/BUILD.gn
index 33beb0516aba2a..b9b2ad32eb9e0a 100644
--- a/llvm/utils/gn/secondary/llvm/test/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/test/BUILD.gn
@@ -64,7 +64,7 @@ write_lit_config("lit_site_cfg") {
     "LLVM_ENABLE_FFI=0",
     "LLVM_ENABLE_HTTPLIB=0",
     "LLVM_FORCE_VC_REVISION=",
-    "LLVM_HAS_LOGF128=0",
+    "LLVM_DISABLE_LOGF128=0",
     "LLVM_HAVE_OPT_VIEWER_MODULES=0",
     "LLVM_HOST_TRIPLE=$llvm_current_triple",
     "LLVM_INCLUDE_DXIL_TESTS=0",
diff --git a/utils/bazel/llvm_configs/llvm-config.h.cmake b/utils/bazel/llvm_configs/llvm-config.h.cmake
index 629977cc11d683..87e6a4c075ca10 100644
--- a/utils/bazel/llvm_configs/llvm-config.h.cmake
+++ b/utils/bazel/llvm_configs/llvm-config.h.cmake
@@ -198,7 +198,7 @@
 /* Define if plugins enabled */
 #cmakedefine LLVM_ENABLE_PLUGINS
 
-/* Define if logf128 is available */
-#cmakedefine LLVM_HAS_LOGF128
+/* Define if logf128 is disabled */
+#cmakedefine LLVM_DISABLE_LOGF128
 
 #endif

@MDevereau MDevereau closed this Feb 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bazel "Peripheral" support tier build system: utils/bazel cmake Build system in general and CMake in particular llvm:adt llvm:analysis llvm:support llvm:transforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants