Version
clang version 15.0.4
Target: aarch64-unknown-linux-gnu
Thread model: posix
Description
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.
Code
#include<stdio.h>
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;
after_use(len);
return;
}
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?
If so, please tell me the PR or commit. Otherwise, just give me some suggestions to solve this, I’ve debug this few days