[PATCH 34/59] x86: Fix THREAD_GSCOPE_RESET_FLAG build on clang

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Mon Oct 20 19:18:49 GMT 2025



On 20/10/25 16:09, Uros Bizjak wrote:
> On Mon, Oct 20, 2025 at 8:47 PM Adhemerval Zanella Netto
> <adhemerval.zanella@linaro.org> wrote:
>>
>>
>>
>> On 19/10/25 12:21, Uros Bizjak wrote:
>>>
>>>
>>> On 10/17/25 21:13, Adhemerval Zanella wrote:
>>>> clang does not support __seg_fs in asm constraint.
>>>> ---
>>>>   sysdeps/x86_64/nptl/tls.h | 21 +++++++++++++++++----
>>>>   1 file changed, 17 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
>>>> index abfeb88054..2c4b9aaa80 100644
>>>> --- a/sysdeps/x86_64/nptl/tls.h
>>>> +++ b/sysdeps/x86_64/nptl/tls.h
>>>> @@ -198,13 +198,26 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
>>>>   # define THREAD_GSCOPE_FLAG_UNUSED 0
>>>>   # define THREAD_GSCOPE_FLAG_USED   1
>>>>   # define THREAD_GSCOPE_FLAG_WAIT   2
>>>> +
>>>> +/* clang does not support __seg_fs in asm constraint.  */
>>>> +# ifdef __clang__
>>>> +#  define XCHGL_GSCOPE(__r)                              \
>>>> +   asm volatile ("xchgl %0, %%fs:%P1"                          \
>>>> +                 : "=r" (__r)                              \
>>>> +                 : "i" (offsetof (struct pthread, header.gscope_flag)),          \
>>>> +           "0" (THREAD_GSCOPE_FLAG_UNUSED))
>>>
>>> This needs a "memory" clobber, because this asm hides memory access
>>> from the compiler. Please see the "memory" special clobber argument
>>> section in [1].
>>>
>>> Also, please use the "c" operand modifier instead of "P". Clang allows
>>> "c" with "i" constraint and also checks that operand fits "c".
>>
>> Ack.
>>
>>>
>>> Clang accepts __seg_fs prefixed addresses, it just "forgets" to emit %fs: prefix in the generated code. While this could be considered a bug with clang, the simplest solution is to just conditionally put "%%fs:" prefix in the asm template for clang.
>>
>> We also need to use a 'i' constraint, clang does not accept 'm' witha
>> '((struct pthread __seg_fs *)0)->header.gscope_flag'.
> 
> Hm, it works for me, at least for the following testcase:
> 
> --cut here--
> struct pthread
> {
>   struct
>   {
>     int multiple_threads;
>     int gscope_flag;
>   } header;
>   void *__padding[24];
> };
> 
> int baz(void)
> {
>   int __res;
>   asm volatile ("xchgl %%fs:%1, %0"
>         : "=r" (__res)
>         : "m" (((struct pthread __seg_fs *)0)->header.gscope_flag),
>           "0" (0));
>   return __res;
> }
> --cut here--
> 
> $ clang -O2 -c tcbc.c
> $ objdump -dr tcbc.o
> 
> 0000000000000000 <baz>:
>   0:   31 c0                   xor    %eax,%eax
>   2:   64 87 04 25 04 00 00    xchg   %eax,%fs:0x4
>   9:   00
>   a:   c3                      ret
> 
> $ clang --version
> clang version 20.1.8 (Fedora 20.1.8-4.fc42)
> Target: x86_64-redhat-linux-gnu

Indeed, it was not working on my side due a wrong constraint for '%1'.
I will update the patch.



More information about the Libc-alpha mailing list