[libc-commits] [libc] [libc] Proof of concept of aliasing long double math functions. (PR #132627)

via libc-commits libc-commits at lists.llvm.org
Mon Mar 24 10:45:08 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: None (lntue)

<details>
<summary>Changes</summary>



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


6 Files Affected:

- (modified) libc/cmake/modules/LLVMLibCArchitectures.cmake (+1) 
- (modified) libc/cmake/modules/LLVMLibCCompileOptionRules.cmake (+4) 
- (modified) libc/src/__support/common.h (+35-9) 
- (modified) libc/src/math/CMakeLists.txt (+25-5) 
- (modified) libc/src/math/generic/copysign.cpp (+9) 
- (modified) libc/src/math/generic/copysignf128.cpp (+8) 


``````````diff
diff --git a/libc/cmake/modules/LLVMLibCArchitectures.cmake b/libc/cmake/modules/LLVMLibCArchitectures.cmake
index 62f3a2e3bdb59..5cdce54accdf3 100644
--- a/libc/cmake/modules/LLVMLibCArchitectures.cmake
+++ b/libc/cmake/modules/LLVMLibCArchitectures.cmake
@@ -150,6 +150,7 @@ if(LIBC_TARGET_ARCHITECTURE STREQUAL "arm")
   set(LIBC_TARGET_ARCHITECTURE_IS_ARM TRUE)
 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "aarch64")
   set(LIBC_TARGET_ARCHITECTURE_IS_AARCH64 TRUE)
+  set(LIBC_TARGET_LONG_DOUBLE_IS_FLOAT128 TRUE)
 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "x86_64")
   set(LIBC_TARGET_ARCHITECTURE_IS_X86_64 TRUE)
 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "i386")
diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
index 0facb0b9be0c1..d20bcc2fdb2cb 100644
--- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
+++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
@@ -118,6 +118,10 @@ function(_get_common_compile_options output_var flags)
   if(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE)
     list(APPEND compile_options "-fpie")
 
+    if(LIBC_TARGET_LONG_DOUBLE_IS_FLOAT128 OR LIBC_TARGET_LONG_DOUBLE_IS_FLOAT64)
+      list(APPEND compile_options "-DLIBC_ALIAS_LONG_DOUBLE")
+    endif()
+
     if(LLVM_LIBC_FULL_BUILD)
       # Only add -ffreestanding flag in non-GPU full build mode.
       if(NOT LIBC_TARGET_OS_IS_GPU)
diff --git a/libc/src/__support/common.h b/libc/src/__support/common.h
index 42e8a79187fac..2ae72edd655e6 100644
--- a/libc/src/__support/common.h
+++ b/libc/src/__support/common.h
@@ -37,21 +37,47 @@
 
 #define LLVM_LIBC_ATTR(name) EXPAND_THEN_SECOND(LLVM_LIBC_FUNCTION_ATTR_##name)
 
-// MacOS needs to be excluded because it does not support aliasing.
-#if defined(LIBC_COPT_PUBLIC_PACKAGING) && (!defined(__APPLE__))
-#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist)                           \
+// MacOS needs to be excluded because it does not support [[gnu::aliasing]].
+#ifndef __APPLE__
+
+#if defined(LIBC_COPT_PUBLIC_PACKAGING)
+#define LLVM_LIBC_FUNCTION(type, name, arglist)                                \
   LLVM_LIBC_ATTR(name)                                                         \
   LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name)                       \
-      __##name##_impl__ __asm__(#name);                                        \
+      __##name##_impl__ asm(#name);                                            \
   decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]];                   \
   type __##name##_impl__ arglist
-#else
-#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) type name arglist
-#endif
 
-// This extra layer of macro allows `name` to be a macro to rename a function.
+#define LLVM_LIBC_ALIASING_FUNCTION(name, func)                                \
+  namespace LIBC_NAMESPACE_DECL {                                              \
+  decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#func)]];                   \
+  asm(#name " = " #func);                                                      \
+  }                                                                            \
+  static_assert(true, "Require semicolon")
+#else
 #define LLVM_LIBC_FUNCTION(type, name, arglist)                                \
-  LLVM_LIBC_FUNCTION_IMPL(type, name, arglist)
+  LLVM_LIBC_ATTR(name)                                                         \
+  LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name)                       \
+      __##name##_impl__ asm("__" #name "_impl__");                             \
+  decltype(LIBC_NAMESPACE::name) name [[gnu::alias("__" #name "_impl__")]];    \
+  type __##name##_impl__ arglist
+
+#define LLVM_LIBC_ALIASING_FUNCTION(name, func)                                \
+  namespace LIBC_NAMESPACE_DECL {                                              \
+  decltype(LIBC_NAMESPACE::name) name [[gnu::alias("__" #func "_impl__")]];    \
+  asm(#name " = __" #func "_impl__");                                          \
+  }                                                                            \
+  static_assert(true, "Require semicolon")
+#endif // LIBC_COPT_PUBLIC_PACKAGING
+
+#else
+
+#define LLVM_LIBC_FUNCTION(type, name, arglist) type name arglist
+
+#define LLVM_LIBC_ALIASING_FUNCTION(name, func)                                \
+  static_assert(true, "Require semicolon")
+
+#endif // !__APPLE__
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 92c80a1053c9e..c86b98c65a6c8 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -7,24 +7,30 @@ function(add_math_entrypoint_object name)
   # We prefer machine specific implementation if available. Hence we check
   # that first and return early if we are able to add an alias target for the
   # machine specific implementation.
-  get_fq_target_name("${LIBC_TARGET_ARCHITECTURE}.${name}" fq_machine_specific_target_name)
+  if(NOT ARGN)
+    set(alias_entrypoint ${name})
+  else()
+    set(alias_entrypoint ${ARGN})
+  endif()
+
+  get_fq_target_name("${LIBC_TARGET_ARCHITECTURE}.${alias_entrypoint}" fq_machine_specific_target_name)
   if(TARGET ${fq_machine_specific_target_name})
     add_entrypoint_object(
       ${name}
       ALIAS
       DEPENDS
-        .${LIBC_TARGET_ARCHITECTURE}.${name}
+        .${LIBC_TARGET_ARCHITECTURE}.${alias_entrypoint}
     )
     return()
   endif()
 
-  get_fq_target_name("generic.${name}" fq_generic_target_name)
+  get_fq_target_name("generic.${alias_entrypoint}" fq_generic_target_name)
   if(TARGET ${fq_generic_target_name})
     add_entrypoint_object(
       ${name}
       ALIAS
       DEPENDS
-        .generic.${name}
+        .generic.${alias_entrypoint}
     )
     return()
   endif()
@@ -40,6 +46,20 @@ function(add_math_entrypoint_object name)
   )
 endfunction()
 
+function(add_long_double_math_entrypoint_object name)
+  get_fq_target_name(${name} fq_double_math_target)
+  get_fq_target_name("${name}l" fq_long_double_math_target)
+  get_fq_target_name("${name}f128" fq_float128_math_target)
+
+  if(LIBC_TARGET_LONG_DOUBLE_IS_DOUBLE)
+    add_math_entrypoint_object("${name}l" "${name}")
+  elseif(LIBC_TARGET_LONG_DOUBLE_IS_FLOAT128)
+    add_math_entrypoint_object("${name}l" "${name}f128")
+  else()
+    add_math_entrypoint_object("${name}l")
+  endif()
+endfunction()
+
 add_math_entrypoint_object(acos)
 add_math_entrypoint_object(acosf)
 add_math_entrypoint_object(acosf16)
@@ -88,9 +108,9 @@ add_math_entrypoint_object(ceilf128)
 
 add_math_entrypoint_object(copysign)
 add_math_entrypoint_object(copysignf)
-add_math_entrypoint_object(copysignl)
 add_math_entrypoint_object(copysignf16)
 add_math_entrypoint_object(copysignf128)
+add_long_double_math_entrypoint_object(copysign)
 
 add_math_entrypoint_object(cos)
 add_math_entrypoint_object(cosf)
diff --git a/libc/src/math/generic/copysign.cpp b/libc/src/math/generic/copysign.cpp
index 186bb2c5983f4..fef1d1f9ad332 100644
--- a/libc/src/math/generic/copysign.cpp
+++ b/libc/src/math/generic/copysign.cpp
@@ -10,6 +10,7 @@
 #include "src/__support/FPUtil/ManipulationFunctions.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
@@ -22,3 +23,11 @@ LLVM_LIBC_FUNCTION(double, copysign, (double x, double y)) {
 }
 
 } // namespace LIBC_NAMESPACE_DECL
+
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64) &&                              \
+    defined(LIBC_ALIAS_LONG_DOUBLE)
+#include "src/math/copysignl.h"
+
+LLVM_LIBC_ALIASING_FUNCTION(copysignl, copysign);
+
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
diff --git a/libc/src/math/generic/copysignf128.cpp b/libc/src/math/generic/copysignf128.cpp
index 9a51c8d5eb8df..7130d55b97f34 100644
--- a/libc/src/math/generic/copysignf128.cpp
+++ b/libc/src/math/generic/copysignf128.cpp
@@ -18,3 +18,11 @@ LLVM_LIBC_FUNCTION(float128, copysignf128, (float128 x, float128 y)) {
 }
 
 } // namespace LIBC_NAMESPACE_DECL
+
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128) &&                             \
+    defined(LIBC_ALIAS_LONG_DOUBLE)
+#include "src/math/copysignl.h"
+
+LLVM_LIBC_ALIASING_FUNCTION(copysignl, copysignf128);
+
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128

``````````

</details>


https://github.com/llvm/llvm-project/pull/132627


More information about the libc-commits mailing list