On 2024-09-27 02:01, Boqun Feng wrote:
#define ADDRESS_EQ(var, expr) \ ({ \ bool _____cmp_res = (unsigned long)(var) == (unsigned long)(expr); \ \ OPTIMIZER_HIDE_VAR(var); \ _____cmp_res; \ })
If the goal is to ensure gcc uses the register populated by the second, I'm afraid it does not work. AFAIU, "hiding" the dependency chain does not prevent the SSA GVN optimization from combining the registers as being one and choosing one arbitrary source. "hiding" the dependency chain before or after the comparison won't help here. int fct_hide_var_compare(void) { int *a, *b; do { a = READ_ONCE(p); asm volatile ("" : : : "memory"); b = READ_ONCE(p); } while (!ADDRESS_EQ(a, b)); return *b; } gcc 14.2 x86-64: fct_hide_var_compare: mov rax,QWORD PTR [rip+0x0] # 67 <fct_hide_var_compare+0x7> mov rdx,QWORD PTR [rip+0x0] # 6e <fct_hide_var_compare+0xe> cmp rax,rdx jne 60 <fct_hide_var_compare> mov eax,DWORD PTR [rax] ret main: xor eax,eax ret gcc 14.2.0 ARM64: fct_hide_var_compare: adrp x0, .LANCHOR0 add x0, x0, :lo12:.LANCHOR0 .L12: ldr x1, [x0] ldr x2, [x0] cmp x1, x2 bne .L12 ldr w0, [x1] ret p: .zero 8 -- Mathieu Desnoyers EfficiOS Inc. https://www.efficios.com