[PATCH 37/59] math: Fix modf{f} build on clang

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Fri Oct 24 11:34:03 GMT 2025



On 24/10/25 03:18, H.J. Lu wrote:
> On Fri, Oct 24, 2025 at 6:28 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>>
>> On Fri, Oct 24, 2025 at 6:19 AM Adhemerval Zanella Netto
>> <adhemerval.zanella@linaro.org> wrote:
>>>
>>>
>>>
>>> On 23/10/25 19:06, H.J. Lu wrote:
>>>> On Fri, Oct 24, 2025 at 5:38 AM Adhemerval Zanella Netto
>>>> <adhemerval.zanella@linaro.org> wrote:
>>>>>
>>>>>
>>>>>
>>>>> On 23/10/25 18:27, H.J. Lu wrote:
>>>>>> On Thu, Oct 23, 2025 at 10:00 PM Adhemerval Zanella Netto
>>>>>> <adhemerval.zanella@linaro.org> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 22/10/25 18:51, H.J. Lu wrote:
>>>>>>>> On Thu, Oct 23, 2025 at 12:26 AM Adhemerval Zanella Netto
>>>>>>>> <adhemerval.zanella@linaro.org> wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 20/10/25 19:09, H.J. Lu wrote:
>>>>>>>>>> On Tue, Oct 21, 2025 at 1:58 AM Adhemerval Zanella Netto
>>>>>>>>>> <adhemerval.zanella@linaro.org> wrote:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On 18/10/25 03:28, H.J. Lu wrote:
>>>>>>>>>>>> On Sat, Oct 18, 2025 at 3:58 AM Adhemerval Zanella
>>>>>>>>>>>> <adhemerval.zanella@linaro.org> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> We need to disable the internal optimize for math builtins
>>>>>>>>>>>>> (NO_MATH_REDIRECT) for the USE_TRUNC_BUILTIN case.
>>>>>>>>>>>>
>>>>>>>>>>>> Does it change GCC codegen?
>>>>>>>>>>>
>>>>>>>>>>> No, both with clang and gcc either the builtin is issues (on
>>>>>>>>>>> aarch64 for instance) or the internal symbol is called.
>>>>>>>>>>
>>>>>>>>>> Why does NO_MATH_REDIRECT make no difference here?
>>>>>>>>>> Why is this macro needed?
>>>>>>>>>
>>>>>>>>> With clang the internal optimization to avoid PLT usage for symbol
>>>>>>>>> that might be inline will make clang to *not* emit the builtin:
>>>>>>>>>
>>>>>>>>> include/math.h
>>>>>>>>>
>>>>>>>>> 177 MATH_REDIRECT (trunc, "__", MATH_REDIRECT_UNARY_ARGS)
>>>>>>>>>
>>>>>>>>> Without NO_MATH_REDIRECT, which disables it; build with clang
>>>>>>>>> fails:
>>>>>>>>>
>>>>>>>>>>>> referenced by s_modf.c:34 ([...]/../sysdeps/ieee754/dbl-64/s_modf.c:34)
>>>>>>>>>>>>               [...]/aarch64-linux-gnu-clang-21/libc_pic.os.clean:(__modf)
>>>>>>>>> clang: error: linker command failed with exit code 1 (use -v to see invocation)
>>>>>>>>>
>>>>>>>>> gcc is not affected by this, it will emit the 'frintz' regardless
>>>>>>>>> of MATH_REDIRECT.
>>>>>>>>
>>>>>>>> So clang won't inline trunc without NO_MATH_REDIRECT?
>>>>>>>> Why isn't gcc impacted?
>>>>>>>>
>>>>>>>
>>>>>>> Here is a simplified testcase:
>>>>>>>
>>>>>>>   extern float truncf (float __x) __attribute__ ((__nothrow__ )) __attribute__ ((__const__));
>>>>>>>   extern float __truncf (float __x) __attribute__ ((__nothrow__ )) __attribute__ ((__const__));
>>>>>>>
>>>>>>>   #ifdef ALIAS
>>>>>>>   float (truncf) (float) asm ("__truncf");
>>>>>>>   #endif
>>>>>>>
>>>>>>>   float foo (float x) { return truncf (x); }
>>>>>>>
>>>>>>> If ALIAS is defined clang will always emit a __truncf call. It seems that alias
>>>>>>> are applied as early as possible, from -emit-llvm -mllvm -print-after-all
>>>>>>> I see that ForceFunctionAttrsPass is the first used and it already issues
>>>>>>> a "%call = call float @__truncf(float noundef %0) #2".
>>>>>>>
>>>>>>
>>>>>> GCC does the same:
>>>>>>
>>>>>> [hjl@gnu-tgl-3 tmp]$ gcc -S -O2 t.c
>>>>>> [hjl@gnu-tgl-3 tmp]$ cat t.s
>>>>>> .file "t.c"
>>>>>> .text
>>>>>> .p2align 4
>>>>>> .globl foo
>>>>>> .type foo, @function
>>>>>> foo:
>>>>>> .LFB0:
>>>>>> .cfi_startproc
>>>>>> jmp truncf
>>>>>> .cfi_endproc
>>>>>> .LFE0:
>>>>>> .size foo, .-foo
>>>>>> .ident "GCC: (GNU) 15.2.1 20250924 (Red Hat 15.2.1-2)"
>>>>>> .section .note.GNU-stack,"",@progbits
>>>>>> [hjl@gnu-tgl-3 tmp]$ gcc -S -O2 t.c -DALIAS
>>>>>> [hjl@gnu-tgl-3 tmp]$ cat t.s
>>>>>> .file "t.c"
>>>>>> .text
>>>>>> .p2align 4
>>>>>> .globl foo
>>>>>> .type foo, @function
>>>>>> foo:
>>>>>> .LFB0:
>>>>>> .cfi_startproc
>>>>>> jmp __truncf
>>>>>> .cfi_endproc
>>>>>> .LFE0:
>>>>>> .size foo, .-foo
>>>>>> .ident "GCC: (GNU) 15.2.1 20250924 (Red Hat 15.2.1-2)"
>>>>>> .section .note.GNU-stack,"",@progbits
>>>>>> [hjl@gnu-tgl-3 tmp]$
>>>>>>
>>>>>> What is the real issue?
>>>>>>
>>>>>
>>>>> That is not what I am seeing https://godbolt.org/z/7YT5Y5PPr . I am not sure
>>>>> why it not triggering in your end.
>>>>
>>>> truncf is always inlined with SSE4 and GCC 16, with and without
>>>> asm ("__truncf").   But clang doesn't inline it with asm ("__truncf").
>>>> Do we want to inline truncf or not?
>>>
>>> Yes, that why the architecture defines USE_TRUNCF_BUILTIN and why I had
>>> to add NO_MATH_REDIRECT. Otherwise clang will emit a libcall and since
>>> libc.so does not have the trunc object the link fails.
>>
>> Can we not define alias when USE_TRUNCF_BUILTIN is defined?
>>
> 
> I opened:
> 
> https://sourceware.org/bugzilla/show_bug.cgi?id=33576
> 

It fixed the build, but this patch now makes aarch64 modf/modff call copysign
instead of inlining. It is because we are missing the USE_COPYSIGN{F}_BUILTIN:

diff --git a/sysdeps/generic/math-use-builtins-copysign.h b/sysdeps/generic/math-use-builtins-copysign.h
index b774931f431..4bca2ee1b10 100644
--- a/sysdeps/generic/math-use-builtins-copysign.h
+++ b/sysdeps/generic/math-use-builtins-copysign.h
@@ -1,4 +1,6 @@
 /* Generic implementations for float and double always use the builtin.  */
+#define USE_COPYSIGNF_BUILTIN 1
+#define USE_COPYSIGN_BUILTIN 1
 #define USE_COPYSIGNL_BUILTIN 1
 #if __GNUC_PREREQ (7, 0)
 # define USE_COPYSIGNF128_BUILTIN 1

I think we should always assume the USE_XXX_BUILTIN existence instead of:

+#ifndef USE_CEIL_BUILTIN
+# define USE_CEIL_BUILTIN 0
+#endif
+#ifndef USE_CEILF_BUILTIN
+# define USE_CEILF_BUILTIN 0
+#endif
+#ifndef USE_CEILL_BUILTIN
+# define USE_CEILL_BUILTIN 0
+#endif
+#ifndef USE_CEILF128_BUILTIN
+# define USE_CEILF128_BUILTIN 0
+#endif

And add such definition if not defined.


More information about the Libc-alpha mailing list