[PATCH] x32: Fix, optimize and cleanup RSEQ_* accessors

Uros Bizjak ubizjak@gmail.com
Mon Aug 25 06:22:57 GMT 2025


On Mon, Aug 25, 2025 at 7:58 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * Uros Bizjak:
>
> >> If you use movzbl, should you change the type of __value to long long
> >> int, to hint to the compiler that the entire register is cleared?
> >
> > No, the fact that the register is cleared is just a side effect of
> > some other x86 (mis-)feature. MOVB to a register is actually an insert
> > to a LSB of the word-sized register, so the result becomes dependent
> > on the previous value of the register. MOVZBL avoids this issue,
>
> I think it's still valuable to tell GCC that the entire register is
> cleared.  Otherwise, this
>
> long int __rseq_offset;
> int
> f (void)
> {
>   unsigned char __value;
>   asm volatile ("movzbl %%fs:%c1(%2), %k0"
>                 : "=r" (__value)
>                 : "i" (0),
>                   "r" ((long long int) __rseq_offset)
>                 : "memory");
>   return __value;
> }
>
> produces an additional movbzl.  On the other hand, it only works for
> unsigned chars.

That would complicate the macro too much for no apparent gain, because
currently we have:

+     __typeof (RSEQ_SELF()->member) __value;

Also, please note that even internal representation in the compiler
does not care about zero-extension:

#(insn:TI 10 2 11 2 (set (reg/i:QI 0 ax)
#        (mem/c:QI (symbol_ref:DI ("foo") [flags 0x2]  <var_decl
0x7f05623c9e40 foo>) [0 foo+0 S1 A8])) "movb.c":6:1 98
{*movqi_internal}
#     (nil))
       movzbl  foo(%rip), %eax # 10    [c=5 l=7]  *movqi_internal/4

so IMO we wouldn't lose much by keepin the macro the way it is.

Uros.


More information about the Libc-alpha mailing list