value extension (or not) during parameter passing

40 views
Skip to first unread message

Jan Beulich

unread,
Feb 21, 2024, 10:38:49 AMFeb 21
to x86-6...@googlegroups.com
Hello,

searching through the ABI text I can't spot any statement as to it being
caller or callee to sign- or zero-extend sub-32-bit values when passing
or returning, with two exceptions: There's a footnote for bool, and
there's another one for the hidden argument of variadic functions. These
two are consistent in leaving it to the callee, and that's also how gcc
behaves. Clang, otoh, appears to be assuming that some suitable extension
was done by the caller.

If there wasn't this difference in behavior between the two compilers,
I'd primarily expect to be overlooking a statement somewhere ...

Jan

Michael Matz

unread,
Feb 21, 2024, 11:15:47 AMFeb 21
to Jan Beulich, x86-6...@googlegroups.com
Hello,

On Wed, 21 Feb 2024, 'Jan Beulich' via X86-64 System V Application Binary Interface wrote:

> searching through the ABI text I can't spot any statement as to it being
> caller or callee to sign- or zero-extend sub-32-bit values when passing
> or returning,

Yes, it was intentionally not specified to be in the caller ...

> with two exceptions: There's a footnote for bool, and
> there's another one for the hidden argument of variadic functions.

... which originally inadvertedly created a problem for these two (given
the C promotion rules for variadic unnamed arguments, and confusion about
which parts of a bool can be relied upon), and so were made explicit.

(Note that not specifying it for the caller implies that the callee
_needs_ to be able to deal with it, be it by extension or by using
appropriately short forms of instructions if possible; there's no need to
specify that explicitely in the psABI).

> These two are consistent in leaving it to the callee, and that's also
> how gcc behaves. Clang, otoh, appears to be assuming that some suitable
> extension was done by the caller.

For which? varargs and bool? Maybe, those came later to the psABI and
merely codified existing behaviour (of GCC). If clang also expects
sext/zext on e.g. short named arguments to have happened in the caller I'd
say they have a bug.


Ciao,
Michael.

Jan Beulich

unread,
Feb 22, 2024, 4:57:24 AMFeb 22
to Michael Matz, x86-6...@googlegroups.com
On 21.02.2024 17:14, Michael Matz wrote:
> On Wed, 21 Feb 2024, 'Jan Beulich' via X86-64 System V Application Binary Interface wrote:
>
>> searching through the ABI text I can't spot any statement as to it being
>> caller or callee to sign- or zero-extend sub-32-bit values when passing
>> or returning,
>
> Yes, it was intentionally not specified to be in the caller ...
>
>> with two exceptions: There's a footnote for bool, and
>> there's another one for the hidden argument of variadic functions.
>
> ... which originally inadvertedly created a problem for these two (given
> the C promotion rules for variadic unnamed arguments, and confusion about
> which parts of a bool can be relied upon), and so were made explicit.
>
> (Note that not specifying it for the caller implies that the callee
> _needs_ to be able to deal with it, be it by extension or by using
> appropriately short forms of instructions if possible; there's no need to
> specify that explicitely in the psABI).

Hmm, for the avoidance of doubt or (as may have happened here) even
misunderstanding, I think it would have been better to explicitly say
this, even if (like for the two cases mentioned) only in a clarifying
footnote.

>> These two are consistent in leaving it to the callee, and that's also
>> how gcc behaves. Clang, otoh, appears to be assuming that some suitable
>> extension was done by the caller.
>
> For which? varargs and bool?

I've taken the text for these two only for reference, the observed issue is
with ...

> Maybe, those came later to the psABI and
> merely codified existing behaviour (of GCC). If clang also expects
> sext/zext on e.g. short named arguments to have happened in the caller I'd
> say they have a bug.

... this kind of parameters, as in e.g.

void vtest(int, ...);

void test(int i, unsigned char uc) {
vtest(i, uc);
}

int test2(int i, unsigned char uc) {
return i + uc;
}

Clang behavior there appears to be pretty stable over a wide range of
versions.

Jan

Florian Weimer

unread,
Feb 22, 2024, 5:02:23 AMFeb 22
to 'Jan Beulich' via X86-64 System V Application Binary Interface, Michael Matz, Jan Beulich
>> Maybe, those came later to the psABI and
>> merely codified existing behaviour (of GCC). If clang also expects
>> sext/zext on e.g. short named arguments to have happened in the caller I'd
>> say they have a bug.
>
> ... this kind of parameters, as in e.g.
>
> void vtest(int, ...);
>
> void test(int i, unsigned char uc) {
> vtest(i, uc);
> }
>
> int test2(int i, unsigned char uc) {
> return i + uc;
> }
>
> Clang behavior there appears to be pretty stable over a wide range of
> versions.

Is this related to this long-standing LLVM issue?

x86-64: sign extension of parameters and returns values should match GCC
<https://github.com/llvm/llvm-project/issues/12579>

Jan Beulich

unread,
Feb 22, 2024, 5:37:01 AMFeb 22
to Florian Weimer, Michael Matz, 'Jan Beulich' via X86-64 System V Application Binary Interface
Looks like so; that's "only" nearly 12 years old ...

Jan

Michael Matz

unread,
Feb 22, 2024, 8:42:54 AMFeb 22
to Jan Beulich, x86-6...@googlegroups.com
Hello,

On Thu, 22 Feb 2024, Jan Beulich wrote:

> > Maybe, those came later to the psABI and
> > merely codified existing behaviour (of GCC). If clang also expects
> > sext/zext on e.g. short named arguments to have happened in the caller I'd
> > say they have a bug.
>
> ... this kind of parameters, as in e.g.
>
> void vtest(int, ...);
>
> void test(int i, unsigned char uc) {
> vtest(i, uc);
> }
>
> int test2(int i, unsigned char uc) {
> return i + uc;
> }
>
> Clang behavior there appears to be pretty stable over a wide range of
> versions.

I see, so they are buggy since a long time then :-/ That's
very unfortunate but nothing we can somehow mitigate in the psABI.


Ciao,
Michael.

Michael Matz

unread,
Feb 22, 2024, 9:03:25 AMFeb 22
to Jan Beulich, x86-6...@googlegroups.com
Heyho again,

On Thu, 22 Feb 2024, Michael Matz wrote:

> > ... this kind of parameters, as in e.g.
> >
> > void vtest(int, ...);
> >
> > void test(int i, unsigned char uc) {
> > vtest(i, uc);
> > }
> >
> > int test2(int i, unsigned char uc) {
> > return i + uc;
> > }
> >
> > Clang behavior there appears to be pretty stable over a wide range of
> > versions.
>
> I see, so they are buggy since a long time then :-/ That's
> very unfortunate but nothing we can somehow mitigate in the psABI.

And it seems I'm forgetting stuff as I was involved in a discussion about
exactly this at

http://gcc.gnu.org/ml/gcc/2013-01/msg00447.html

They tried to fix it at https://reviews.llvm.org/D72742 but then became
nervous about becoming incompatible with themself (which doesn't make
sense, when doing extensions in the callee it doesn't matter what the
caller did) and speculating that GCC may "fix" this problem by also
extending in the caller because it clearly "most often does already".

That the latter is by virtue of the x86-64 instruction set and
happenstance, rather than by design, didn't seem to occur to them and so
they believed that GCC doing the extension sometimes (falsly believed to
be doing it always) is the ABI, not the psABI. They somehow also
convinced themself that GCC not extending in the caller only happens very
rarely, and so decided that it's not _that_ important a change to do in
llvm.

So, huh?


Ciao,
Michael.

Jan Beulich

unread,
Feb 22, 2024, 9:31:21 AMFeb 22
to Michael Matz, x86-6...@googlegroups.com
Indeed. Thanks for digging this out.

Jan
Reply all
Reply to author
Forward
0 new messages