Skip to content

[libcxx] Do not redeclare lgamma_r when targeting the LLVM C library #102036

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

Merged
merged 3 commits into from
Aug 27, 2024

Conversation

jhuber6
Copy link
Contributor

@jhuber6 jhuber6 commented Aug 5, 2024

Summary:
We use lgamma_r for the random normal distribution support. In this
code we redeclare it, which caused issues with the LLVM C library as
this function is marked noexcept in LLVM libc. Also make sure we include
features.h when using the GPU so it gets this as well.

@jhuber6 jhuber6 requested a review from a team as a code owner August 5, 2024 18:43
@jhuber6 jhuber6 requested review from ldionne, mordante and philnik777 and removed request for a team August 5, 2024 18:43
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Aug 5, 2024
@llvmbot
Copy link
Member

llvmbot commented Aug 5, 2024

@llvm/pr-subscribers-libcxx

Author: Joseph Huber (jhuber6)

Changes

Summary:
We use lgamma_r for the random normal distrubtion support. In this
code we redeclare it, which caused issues with the LLVM C library as
this function has the noexcept flag. Also make sure we include
features.h when using the GPU so it gets this as well.


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

2 Files Affected:

  • (modified) libcxx/include/__configuration/platform.h (+3-1)
  • (modified) libcxx/include/__random/binomial_distribution.h (+2-1)
diff --git a/libcxx/include/__configuration/platform.h b/libcxx/include/__configuration/platform.h
index 27f68d04e8a8d..a53ec7d5f7b4a 100644
--- a/libcxx/include/__configuration/platform.h
+++ b/libcxx/include/__configuration/platform.h
@@ -38,7 +38,9 @@
 #  else
 #    define _LIBCPP_GLIBC_PREREQ(a, b) 0
 #  endif // defined(__GLIBC_PREREQ)
-#endif   // defined(__linux__)
+#elif defined(__AMDGPU__) || defined(__NVPTX__)
+#  include <features.h>
+#endif
 
 #ifndef __BYTE_ORDER__
 #  error                                                                                                               \
diff --git a/libcxx/include/__random/binomial_distribution.h b/libcxx/include/__random/binomial_distribution.h
index e8774bb8d67ee..3f19746bae238 100644
--- a/libcxx/include/__random/binomial_distribution.h
+++ b/libcxx/include/__random/binomial_distribution.h
@@ -97,7 +97,8 @@ class _LIBCPP_TEMPLATE_VIS binomial_distribution {
   }
 };
 
-#ifndef _LIBCPP_MSVCRT_LIKE
+// The LLVM C library provides this with conflicting `noexcept` attributes.
+#if !defined(_LIBCPP_MSVCRT_LIKE) && !defined(__LLVM_LIBC__)
 extern "C" double lgamma_r(double, int*);
 #endif
 

@@ -38,7 +38,9 @@
# else
# define _LIBCPP_GLIBC_PREREQ(a, b) 0
# endif // defined(__GLIBC_PREREQ)
#endif // defined(__linux__)
#elif defined(__AMDGPU__) || defined(__NVPTX__)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me wonder if we should instead do this:

// <features.h> defines macros that allows detecting the libc we're using
#if __has_include(<features.h>)
#  include <features.h>
#endif
#if defined(__GLIBC_PREREQ)
  // etc...
#endif

Can you try that out and see if that breaks anything in the CI?

Summary:
We use `lgamma_r` for the random normal distrubtion support. In this
code we redeclare it, which caused issues with the LLVM C library as
this function has the `noexcept` flag. Also make sure we include
`features.h` when using the GPU so it gets this as well.
@jhuber6
Copy link
Contributor Author

jhuber6 commented Aug 21, 2024

ping

1 similar comment
@jhuber6
Copy link
Contributor Author

jhuber6 commented Aug 27, 2024

ping

@ldionne ldionne merged commit 5f2389d into llvm:main Aug 27, 2024
58 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 27, 2024

LLVM Buildbot has detected a new failure on builder sanitizer-ppc64le-linux running on ppc64le-sanitizer while building libcxx at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/72/builds/2687

Here is the relevant piece of the build log for the reference
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure)
...
PASS: ThreadSanitizer-powerpc64le :: mutex_lock_destroyed.cpp (2370 of 2489)
PASS: ScudoStandalone-Unit :: ./ScudoUnitTest-powerpc64le-Test/262/277 (2371 of 2489)
PASS: ThreadSanitizer-powerpc64le :: race_on_read.cpp (2372 of 2489)
PASS: ThreadSanitizer-powerpc64le :: free_race2.c (2373 of 2489)
PASS: ThreadSanitizer-powerpc64le :: pthread_atfork_deadlock3.c (2374 of 2489)
PASS: MemorySanitizer-POWERPC64LE :: sigaction.cpp (2375 of 2489)
PASS: ThreadSanitizer-powerpc64le :: simple_race.cpp (2376 of 2489)
PASS: MemorySanitizer-POWERPC64LE :: chained_origin_memcpy.cpp (2377 of 2489)
PASS: ThreadSanitizer-powerpc64le :: suppressions_mutex.cpp (2378 of 2489)
PASS: ThreadSanitizer-powerpc64le :: thread_end_with_ignore3.cpp (2379 of 2489)
FAIL: ThreadSanitizer-powerpc64le :: signal_block.cpp (2380 of 2489)
******************** TEST 'ThreadSanitizer-powerpc64le :: signal_block.cpp' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 1: /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/build_default/./bin/clang  -fsanitize=thread -Wall  -m64 -fno-function-sections   -gline-tables-only -I/home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/../ -O1 /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp -o /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/POWERPC64LEConfig/Output/signal_block.cpp.tmp &&  /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/POWERPC64LEConfig/Output/signal_block.cpp.tmp 2>&1 | FileCheck /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp
+ /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/build_default/./bin/clang -fsanitize=thread -Wall -m64 -fno-function-sections -gline-tables-only -I/home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/../ -O1 /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp -o /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/POWERPC64LEConfig/Output/signal_block.cpp.tmp
+ /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/POWERPC64LEConfig/Output/signal_block.cpp.tmp
+ FileCheck /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp
/home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp:59:15: error: CHECK-NOT: excluded string found in input
// CHECK-NOT: WARNING: ThreadSanitizer:
              ^
<stdin>:2:1: note: found here
WARNING: ThreadSanitizer: signal handler spoils errno (pid=3652558)
^~~~~~~~~~~~~~~~~~~~~~~~~

Input file: <stdin>
Check file: /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp

-dump-input=help explains the following input dump.

Input was:
<<<<<<
        1: ================== 
        2: WARNING: ThreadSanitizer: signal handler spoils errno (pid=3652558) 
not:59     !~~~~~~~~~~~~~~~~~~~~~~~~                                            error: no match expected
        3:  Signal 10 handler invoked at: 
        4:  #0 handler(int) /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp:13 (signal_block.cpp.tmp+0xff1a0) 
        5:  #1 thread(void*) /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp:25:5 (signal_block.cpp.tmp+0xff2f0) 
        6:  
        7: SUMMARY: ThreadSanitizer: signal handler spoils errno /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp:13 in handler(int) 
        8: ================== 
        9: DONE 
       10: ThreadSanitizer: reported 1 warnings 
>>>>>>

--

Step 9 (test compiler-rt debug) failure: test compiler-rt debug (failure)
...
PASS: ThreadSanitizer-powerpc64le :: mutex_lock_destroyed.cpp (2370 of 2489)
PASS: ScudoStandalone-Unit :: ./ScudoUnitTest-powerpc64le-Test/262/277 (2371 of 2489)
PASS: ThreadSanitizer-powerpc64le :: race_on_read.cpp (2372 of 2489)
PASS: ThreadSanitizer-powerpc64le :: free_race2.c (2373 of 2489)
PASS: ThreadSanitizer-powerpc64le :: pthread_atfork_deadlock3.c (2374 of 2489)
PASS: MemorySanitizer-POWERPC64LE :: sigaction.cpp (2375 of 2489)
PASS: ThreadSanitizer-powerpc64le :: simple_race.cpp (2376 of 2489)
PASS: MemorySanitizer-POWERPC64LE :: chained_origin_memcpy.cpp (2377 of 2489)
PASS: ThreadSanitizer-powerpc64le :: suppressions_mutex.cpp (2378 of 2489)
PASS: ThreadSanitizer-powerpc64le :: thread_end_with_ignore3.cpp (2379 of 2489)
FAIL: ThreadSanitizer-powerpc64le :: signal_block.cpp (2380 of 2489)
******************** TEST 'ThreadSanitizer-powerpc64le :: signal_block.cpp' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 1: /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/build_default/./bin/clang  -fsanitize=thread -Wall  -m64 -fno-function-sections   -gline-tables-only -I/home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/../ -O1 /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp -o /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/POWERPC64LEConfig/Output/signal_block.cpp.tmp &&  /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/POWERPC64LEConfig/Output/signal_block.cpp.tmp 2>&1 | FileCheck /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp
+ /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/build_default/./bin/clang -fsanitize=thread -Wall -m64 -fno-function-sections -gline-tables-only -I/home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/../ -O1 /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp -o /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/POWERPC64LEConfig/Output/signal_block.cpp.tmp
+ /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/POWERPC64LEConfig/Output/signal_block.cpp.tmp
+ FileCheck /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp
/home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp:59:15: error: CHECK-NOT: excluded string found in input
// CHECK-NOT: WARNING: ThreadSanitizer:
              ^
<stdin>:2:1: note: found here
WARNING: ThreadSanitizer: signal handler spoils errno (pid=3652558)
^~~~~~~~~~~~~~~~~~~~~~~~~

Input file: <stdin>
Check file: /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp

-dump-input=help explains the following input dump.

Input was:
<<<<<<
        1: ================== 
        2: WARNING: ThreadSanitizer: signal handler spoils errno (pid=3652558) 
not:59     !~~~~~~~~~~~~~~~~~~~~~~~~                                            error: no match expected
        3:  Signal 10 handler invoked at: 
        4:  #0 handler(int) /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp:13 (signal_block.cpp.tmp+0xff1a0) 
        5:  #1 thread(void*) /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp:25:5 (signal_block.cpp.tmp+0xff2f0) 
        6:  
        7: SUMMARY: ThreadSanitizer: signal handler spoils errno /home/buildbots/llvm-external-buildbots/workers/ppc64le-sanitizer/sanitizer-ppc64le/build/llvm-project/compiler-rt/test/tsan/signal_block.cpp:13 in handler(int) 
        8: ================== 
        9: DONE 
       10: ThreadSanitizer: reported 1 warnings 
>>>>>>

--


@jhuber6 jhuber6 deleted the features branch September 23, 2024 13:26
Comment on lines +33 to +34
// To detect which libc we're using
#if __has_include(<features.h>)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When pre-qualifying LLVM 20, we just found out that this breaks some code. Indeed, folks are free to have a header named <features.h> available on their include paths, and in fact it seems not uncommon to have that. So the __has_include(<features.h>) is going to lie, and the #include <features.h> is going to pick up the wrong one anyway.

We'd need to find another header we can include to provide this version macro. Since C lacks a standardized header to provide version stuff (what a shame), we often rely on using some minimal header like <iso646.h> to get implementation-specific values. That should work for glibc, and llvm-libc could be changed to provide a <iso646.h> header. Also, all of llvm-libc's headers should define the feature macros like __LLVM_LIBC__, which I think is not the case right now.

CCing @var-const @jhuber6 @michaelrj-google

ldionne added a commit to ldionne/llvm-project that referenced this pull request Feb 3, 2025
…library (llvm#102036)"

This reverts commit 5f2389d. That commit started checking whether
<features.h> was a valid include, however codebases are free to have
such a header on their search path, which breaks compilation. LLVM libc
should instead provide a more standard way of getting configuration macros
like __LLVM_LIBC__.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants