Global TLS var CodenGen error in Aarch64

godbolt clang 15.0.0


clang version 15.0.4
Target: aarch64-unknown-linux-gnu
Thread model: posix


Generate TLS var code between two CSEL instruction, so there have a blr instruction between two CSEL instruction. And the two
CSEL instructions have the same condition flag. But blr instruction will change the condition flags. So I think maybe it’s a error.


typedef int (*after_use_call)(unsigned long);

typedef struct StructA {
    unsigned short int a;
    unsigned short int b;
} StructA;

typedef struct StructB {
    unsigned short int a;
    unsigned short int b;
    unsigned short int c;
    unsigned short int d;
} StructB;

extern StructA struct_a_array[56];
extern __thread unsigned int g_tls_var;

StructB struct_b = { 0 };

extern unsigned int return_bool_call(void);

void tls_error(after_use_call after_use)
    unsigned short int len;
    unsigned short int b;
    unsigned int bo;

    bo = return_bool_call();
    len = bo ? sizeof(StructB) : sizeof(StructB) + 24;
    b = struct_a_array[g_tls_var].b;

    struct_b.a = b + 1;
    struct_b.b = (len & 0x00EEE) << 8 | (len & 0xEE00E) >> 8;


Command: clang test.c -O2 -fPIC -S -o test.s

Maybe error AS


        cmp     w0, #0  
        mov     w9, #8192
        csel    w8, w9, w8, eq
        adrp    x0, :tlsdesc:g_tls_var
        ldr     x1, [x0, :tlsdesc_lo12:g_tls_var]
        add     x0, x0, :tlsdesc_lo12:g_tls_var
        blr     x1                                             ; condition flags maybe change
        adrp    x10, :got:struct_a_array
        mrs     x9, TPIDR_EL0
        ldr     w9, [x9, x0]
        mov     w11, #32
        ldr     x10, [x10, :got_lo12:struct_a_array]
        add     x9, x10, x9, lsl #2
        mov     w10, #8
        csel    x0, x11, x10, eq                        ; if change, then two `csel` not Consistent

Additionly, I find the lastest release seem fix this error?

godbolt clang trunk

If so, please tell me the PR or commit. Otherwise, just give me some suggestions to solve this, I’ve debug this few days

My guess is that this change ⚙ D143157 [AArch64] Add NZCV Def for TLSDESC_CALLSEQ [AArch64] Add NZCV Def for TLSDESC_CALLSEQ will be responsible for the change.

1 Like

I try rebuild clang, it seem work. So THX. Let me check it again.