AArch64_be generate diff code for int8_t with AArch64_le?

I test follow code

#include <stdint.h>
int foo(int8_t var1)
    return var1 + var1;

which in godblot aarch64_be clang 15.0.0 generate follow assemble

foo:                                    // @foo
        sub     sp, sp, #16
        strb    w0, [sp, #12]
        ldrsb   w8, [sp, #12]
        add     w0, w8, w8
        add     sp, sp, #16

But, in the godblot aarch64 le clang 15.0.0 generate follow

foo:                                    // @foo
        sub     sp, sp, #16
        strb    w0, [sp, #15]
        ldrsb   w8, [sp, #15]
        ldrsb   w9, [sp, #15]
        add     w0, w8, w9
        add     sp, sp, #16

The diff is the instruction strb store param var1 to 1(16-15) byte or 4(16-12) bytes which the type of var1 is int8_t. So, I think the code generated by aarch64_le is more reasonable than aarch64_be.

I want to know how to fix it, or which part of code impact this behavior.

This is somewhere in GlobalISel-specific code; compiling both with -fno-global-isel yields identical code for both.

Hi, I found in the clang trunk still generate 15 even set the option -fno-global-isel. I wonder whether have some new changes impact this, and is which commit?

So does aarch64-linux-gnu. The point is that big-endian and little-endian only diverge when GlobalISel is enabled.

BigEndian is not a thing:

It will fall back to SDAG.

But in the source code, the aarch64 not impl the function enableBigEndian, so the enableBigEndian default return false. Is somewhere else code impact this behavior?

You can try:

cc -Rpass-missed='gisel*' -fglobal-isel .... foo.c

It will give you remarks about what happened.

Hi, I try it. And report

clang-15: warning: -fglobal-isel support for the 'aarch64_be' architecture is incomplete [-Wglobal-isel]
foo.c:28:1: remark: unable to translate in big endian mode [-Rpass-missed=gisel-irtranslator]
warning: Instruction selection used fallback path for foo [-Wbackend-plugin]
1 warning generated.

New progress:in clang aarch64_be trunk the instruction strb store param var1 to 1(16-15) byte, and in clang aarch64_be 15.0.0 is 4(16-12) bytes.
I guess have a commit fixed this problem, but I don’t know which. Maybe I can learn some thing from it.

It would be unsurprising if GlobalISel has big endian bugs

+1.I remember that somebody did BE fixes in GlobalISel. I forgot who and didn’t found it anymore.

Yeap, I see this commit, and also override the method for aarch64 like:

bool enableBigEndian() const { return true; }

A lot of problems is coming. :joy:

Why big endian is so unwelcome?

Because so far all of GlobalISel’s supported architectures have been little-endian, and so there are likely places where GlobalISel accidentally assumes the architecture is little-endian rather than checking and doing something different for big-endian.