# HG changeset patch # User Taylor R Campbell # Date 1778943563 0 # Sat May 16 14:59:23 2026 +0000 # Branch trunk # Node ID a4a4770864657061ca9abe602fdacaecf659b561 # Parent 4b096084d48b7231fbaeef6fbb718731f7e43289 # EXP-Topic riastradh-pr60272-atomicstackspill WIP: sys/atomic.h: Avoid needless stack spillage with typeof_unqual. Using typeof_unqual strips the volatile qualifier on the local temporaries, so the compiler doesn't issue store/load cycles for access to them. PR kern/60272: sys/atomic.h: unnecessary stack spillage diff -r 4b096084d48b -r a4a477086465 sys/sys/atomic.h --- a/sys/sys/atomic.h Wed May 13 02:40:08 2026 +0000 +++ b/sys/sys/atomic.h Sat May 16 14:59:23 2026 +0000 @@ -406,6 +406,12 @@ void membar_datadep_consumer(void); #define __ATOMIC_SIZE_MAX 4 #endif +#if __GNUC_PREREQ__(14, 0) && !defined(__clang__) +#define __atomic_typeof_unqual __typeof_unqual__ +#else +#define __atomic_typeof_unqual __typeof__ +#endif + /* * We assume that access to an aligned pointer to a volatile object of * at most __ATOMIC_SIZE_MAX bytes is guaranteed to be atomic. This is @@ -422,7 +428,7 @@ void membar_datadep_consumer(void); void kcsan_atomic_load(const volatile void *, void *, int); void kcsan_atomic_store(volatile void *, const void *, int); #define __BEGIN_ATOMIC_LOAD(p, v) \ - union { __typeof__(*(p)) __al_val; char __al_buf[1]; } v; \ + union { __atomic_typeof_unqual(*(p)) __al_val; char __al_buf[1]; } v; \ kcsan_atomic_load(p, v.__al_buf, sizeof(v.__al_val)) #define __END_ATOMIC_LOAD(v) \ (v).__al_val @@ -430,7 +436,7 @@ void kcsan_atomic_store(volatile void *, kcsan_atomic_store(p, __UNVOLATILE(&v), sizeof(v)) #else #define __BEGIN_ATOMIC_LOAD(p, v) \ - __typeof__(*(p)) v = *(p) + const __atomic_typeof_unqual(*(p)) v = *(p) #define __END_ATOMIC_LOAD(v) \ v #ifdef __HAVE_HASHLOCKED_ATOMICS @@ -471,7 +477,7 @@ void kcsan_atomic_store(volatile void *, #define atomic_store_relaxed(p,v) \ ({ \ volatile __typeof__(*(p)) *__as_ptr = (p); \ - __typeof__(*(p)) __as_val = (v); \ + const __atomic_typeof_unqual(*(p)) __as_val = (v); \ __ATOMIC_PTR_CHECK(__as_ptr); \ __DO_ATOMIC_STORE(__as_ptr, __as_val); \ }) @@ -479,7 +485,7 @@ void kcsan_atomic_store(volatile void *, #define atomic_store_release(p,v) \ ({ \ volatile __typeof__(*(p)) *__as_ptr = (p); \ - __typeof__(*(p)) __as_val = (v); \ + const __atomic_typeof_unqual(*(p)) __as_val = (v); \ __ATOMIC_PTR_CHECK(__as_ptr); \ membar_release(); \ __DO_ATOMIC_STORE(__as_ptr, __as_val); \ @@ -549,7 +555,7 @@ static __inline __always_inline void #else #define atomic_load_consume(p) \ ({ \ - const __typeof__(*(p)) __al_val = atomic_load_relaxed(p); \ + const __atomic_typeof_unqual(*(p)) __al_val = atomic_load_relaxed(p); \ membar_datadep_consumer(); \ __al_val; \ })