[PATCH] build: Fix multiple test failures with Clang and lld
maozhao
2663432997@qq.com
Fri Sep 26 09:16:50 GMT 2025
When building Glibc with a full LLVM toolchain (Clang 18.1.8, ld.lld), several tests in the `math`, `conform`, and `elf` suites fail. This patch addresses these issues to improve compatibility with Clang/LLVM.
The failures and their fixes are as follows:
1. **math/test-tgmath* and conform/*tgmath.h* failures:**
The existing math/Makefile contains logic to disable Glibc's <tgmath.h> when Clang is detected, assuming Clang will use its own built-in version. This leads to test failures. Furthermore, the legacy `fabs` macro definition in Glibc's <tgmath.h> is not fully compatible with Clang's diagnostics.
This is fixed by:
- Removing the `no-include` workaround from math/Makefile, forcing the tests to use Glibc's <tgmath.h>.
- Updating the `fabs` macro in <tgmath.h> to use a C11 `_Generic` implementation for Clang and modern GCC. This provides better diagnostics, avoids `-Wabsolute-value` warnings, and passes the tests.
- Adding a check in <tgmath.h> to ensure the Glibc header is prioritized during conformance tests.
2. **elf/ifuncmain* failures with GNU ld:**
When compiled with Clang, several `ifunc` tests fail during linking with the default GNU ld. Switching the linker to `ld.lld` resolves these `ifunc` related failures. While this is a configuration change, it is a prerequisite for a full Clang-based build and exposes the next issue.
3. **elf/tst-isa-level-1 failure with ld.lld:**
Using `ld.lld` introduces a new failure in `elf/tst-isa-level-1`. The test expects `dlopen()` of `tst-isa-level-mod-1-v4.so` to fail on CPUs without x86-64-v4 support. This check relies on the `GNU_PROPERTY_X86_ISA_1_NEEDED` property in the `.note.gnu.property` section of the shared object.
The root cause is that `ld.lld` discards this note section when it originates from `csu/abi-note.o` during the final link. As a result, the dynamic linker sees no ISA requirement, successfully loads the library, and causes the test to fail because it expected an error.
This is resolved by modifying `sysdeps/x86/abi-note.c` and `sysdeps/x86/isa-level.c` to emit the property note into a section that `ld.lld` correctly preserves in the final linked object (e.g., `.note.gnu-clang.property`), thus restoring the test's expected behavior.
After these changes, the mentioned test suites pass successfully when building with Clang and linking with lld.
Tested on x86_64 with LLVM/Clang 18.1.8 and `make check`.
* math/Makefile: Remove `no-include` logic for tgmath tests with
Clang.
* math/tgmath.h (fabs): Use C11 `_Generic` implementation for Clang
and modern GCC.
(internal macro): Add check to ensure Glibc header is used for
conformance tests.
* sysdeps/x86/abi-note.c: Emit ISA property note in a section
preserved by ld.lld.
* sysdeps/x86/isa-level.c: Likewise.
Signed-off-by: maozhao <2663432997@qq.com>
---
math/Makefile | 12 ++++++------
math/tgmath.h | 16 ++++++++++++++++
sysdeps/x86/abi-note.c | 2 +-
sysdeps/x86/isa-level.c | 2 +-
4 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/math/Makefile b/math/Makefile
index c350914290..8c5bb13a4c 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -1070,13 +1070,13 @@ $(objpfx)test-tgmath3-macro-list.out: gen-tgmath-tests.py
$(PYTHON) $< check-list $(tgmath3-macros) > $@; \
$(evaluate-test)
-ifeq ($(have-test-clang),yes)
+#ifeq ($(have-test-clang),yes)
# NB: Clang has its own <tgmath.h> and doesn't use <tgmath.h> from glibc.
-define no-include
-$(1).c-no-include-dot = yes
-endef
-$(foreach m,$(tests-tgmath),$(eval $(call no-include,$(m))))
-endif
+#define no-include
+#$(1).c-no-include-dot = yes
+#endef
+#$(foreach m,$(tests-tgmath),$(eval $(call no-include,$(m))))
+#endif
libm-test-fast-math-cflags = -fno-builtin -D__FAST_MATH__ -DTEST_FAST_MATH
libm-test-vec-cflags = $(libm-test-fast-math-cflags) -fno-inline \
diff --git a/math/tgmath.h b/math/tgmath.h
index cc525e4a2e..337ffa384f 100644
--- a/math/tgmath.h
+++ b/math/tgmath.h
@@ -941,7 +941,23 @@
#define ceil(Val) __TGMATH_UNARY_REAL_ONLY (Val, ceil)
/* Absolute value of X. */
+#if __GNUC_PREREQ (4, 9) || defined(__clang__)
+/* Use a C11 _Generic implementation for Clang and modern GCC to provide
+ better diagnostics and avoid false positives from -Wabsolute-value. This
+ is a baseline implementation using only standard C types. */
+#define fabs(x) _Generic((x), \
+ long double: fabsl, \
+ double: fabs, \
+ float: fabsf, \
+ long double _Complex: cabsl, \
+ double _Complex: cabs, \
+ float _Complex: cabsf, \
+ default: fabs \
+ )(x)
+#else
+/* Fallback to the legacy implementation for older compilers. */
#define fabs(Val) __TGMATH_UNARY_REAL_IMAG_RET_REAL (Val, fabs, cabs)
+#endif
/* Largest integer not greater than X. */
#define floor(Val) __TGMATH_UNARY_REAL_ONLY (Val, floor)
diff --git a/sysdeps/x86/abi-note.c b/sysdeps/x86/abi-note.c
index 9525d24df9..107498cacd 100644
--- a/sysdeps/x86/abi-note.c
+++ b/sysdeps/x86/abi-note.c
@@ -25,5 +25,5 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#include <isa-level.c>
+//#include <isa-level.c>
#include <csu/abi-note.c>
diff --git a/sysdeps/x86/isa-level.c b/sysdeps/x86/isa-level.c
index be0b9b0c9e..136a8f7378 100644
--- a/sysdeps/x86/isa-level.c
+++ b/sysdeps/x86/isa-level.c
@@ -71,7 +71,7 @@
# define note_stringify(arg) note_stringify_1(arg)
# define note_stringify_1(arg) #arg
-asm(".pushsection \".note.gnu.property\",\"a\",@note\n"
+asm(".pushsection \".note.gnu-clang.property\",\"a\",@note\n"
" .p2align " note_stringify (PROPERTY_ALIGN)
/* name length. */
"\n .long 1f - 0f\n"
--
2.34.1
More information about the Libc-alpha
mailing list