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
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down
17 changes: 6 additions & 11 deletions llvm/cmake/config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
15 changes: 3 additions & 12 deletions llvm/include/llvm/ADT/APFloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down Expand Up @@ -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;

/// @}
Expand Down Expand Up @@ -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.
///
Expand Down
8 changes: 0 additions & 8 deletions llvm/include/llvm/ADT/APInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions llvm/include/llvm/Config/llvm-config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
14 changes: 6 additions & 8 deletions llvm/include/llvm/Support/float128.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 0 additions & 4 deletions llvm/lib/Analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,3 @@ add_llvm_component_library(LLVMAnalysis
Support
TargetParser
)

if(LLVM_HAS_LOGF128)
target_compile_definitions(LLVMAnalysis PRIVATE HAS_LOGF128)
endif()
29 changes: 24 additions & 5 deletions llvm/lib/Analysis/ConstantFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down
24 changes: 2 additions & 22 deletions llvm/lib/Support/APFloat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll
Original file line number Diff line number Diff line change
@@ -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)

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
2 changes: 1 addition & 1 deletion llvm/test/lit.site.cfg.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion llvm/utils/gn/secondary/llvm/test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions utils/bazel/llvm_configs/llvm-config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading