Problem with Aarch64 ?


I am facing an issue with a small test where there is a chance that sign-extension is not introduced as expected -

#include <stdio.h>

void func( long x )
printf(" %ld \n", x);

int main()
char c = -1;
func ( c ); // c is zero extended to x
return 0;

generated IR -

define i32 @main() #0 {

store i8 -1, i8* %c, align 1
%2 = load i8, i8* %c, align 1
%3 = zext i8 %2 to i64
call void @func(i64 %3)

The value to the formal argument is zero-extended, different from x86_64. Is this a known issue ? Am I missing anything ?


I believe the signedness of char is implementation defined, have you tried using signed char?

You are right! Now the generated code is -

%3 = sext i8 %2 to i64

This is specified in the ABI document:
Documentation – Arm Developer.

Section 7.1 gives mappings from C types to underlying ones and says
that "char" is actually an "unsigned byte". This applies to 32-bit
AAPCS targets as well; but beware that Darwin targets don't follow
AAPCS here, and char is signed again.


Was there any specific reason to take the opposite path (from x86) ? - Just curious to know.

Not that I know of. The decision would have been made when ARM was
primarily used in pretty embedded situations, long before x86
compatibility was something to even think about.

In that context you could argue that unsigned makes more sense for
typical bit-banging that goes on ("a << 8 | b" etc), but I have no
idea if anyone actually did argue that or they just tossed a coin.