[PATCH] riscv/atomic: Do proper sign extension also for unsigned in arch_cmpxchg

Jessica Clarke jrtc27 at jrtc27.com
Thu Jan 30 09:21:28 PST 2025


On 30 Jan 2025, at 15:53, Andreas Schwab <schwab at suse.de> wrote:
> 
> On Jan 30 2025, Alexandre Ghiti wrote:
> 
>> a2 is used as it is passed by the calling function, so we can't be sure a2
>> is sign extended to me, what am I missing?
> 
> 32-bit scalar arguments are guaranteed to be sign extended on entry.

Firstly, the calling convention is irrelevant if the function is
inlined, which this almost always will be.

Secondly, whilst GCC (still?) maintains the invariant that 32-bit
registers are kept sign-extended in registers on RISC-V, and there’s a
non-normative note in the unprivileged spec about this, LLVM does not,
any extra bits are wholly unspecified, so you must not write inline
assembly that depends on them being well-define, either by ignoring the
bits or by converting your arguments to be whole-register types. If
your compiler has already extended the value in the manner you care
about then that’ll be a no-op, and if it hasn’t then it’ll do what you
need.

We had an issue like this years ago in FreeBSD (also for a uint32_t
CAS) and this was the conclusion I reached [1].

Jess

[1] https://reviews.freebsd.org/D22084




More information about the linux-riscv mailing list