[PATCH 1/3] math: Add ptr_barrier to hide constant table addresses from the compiler

Adhemerval Zanella adhemerval.zanella@linaro.org
Wed Sep 16 16:57:34 GMT 2026


GCC folds each read of a static constant table with a visible
initializer into a separate floating-point literal.  On aarch64 with
GCC 13, 14 and 15 every literal is placed in a mergeable section that
cannot use section anchors, so each one costs an ADRP and a LDR pair
instead of one address computation followed by LDP loads.

For instance the accurate path of acosf materializes its 16 polynomial
coefficients with 16 ADRP/LDR pair.  GCC 16 fixes this for constants of
8 bytes or less (PR target/121240), but not for the 16-byte _Float128
constants used by the ldbl-128 code.

The AArch64 vector routines already avoid this by reading their data
through an asm barrier that hides the table address.  Move that macro
to a new sysdeps header, math-ptr-barrier.h, so the scalar code can use
it as well.

No function changes, checked with a build for aarch64-linux-gnu,
x86_64-linux-gnu, arm-linux-gnueabihf, and i686-linux-gnu.
---
 sysdeps/aarch64/fpu/math-ptr-barrier.h | 33 ++++++++++++++++++++++++++
 sysdeps/aarch64/fpu/vecmath_config.h   | 10 +-------
 sysdeps/generic/math-ptr-barrier.h     | 24 +++++++++++++++++++
 sysdeps/ieee754/dbl-64/math_config.h   |  1 +
 sysdeps/ieee754/flt-32/math_config.h   |  1 +
 5 files changed, 60 insertions(+), 9 deletions(-)
 create mode 100644 sysdeps/aarch64/fpu/math-ptr-barrier.h
 create mode 100644 sysdeps/generic/math-ptr-barrier.h

diff --git a/sysdeps/aarch64/fpu/math-ptr-barrier.h b/sysdeps/aarch64/fpu/math-ptr-barrier.h
new file mode 100644
index 00000000000..5c37d2d7d68
--- /dev/null
+++ b/sysdeps/aarch64/fpu/math-ptr-barrier.h
@@ -0,0 +1,33 @@
+/* Barrier for hiding the address of constant data from the compiler.
+   AArch64 version.
+   Copyright (C) 2026 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef AARCH64_MATH_PTR_BARRIER_H
+#define AARCH64_MATH_PTR_BARRIER_H 1
+
+/* Return PTR but hide its value from the compiler so accesses through it
+   cannot be optimized based on the contents.  Without it, GCC might folds
+   each element of a static constant table into a separate literal.  */
+#define ptr_barrier(ptr)						\
+  ({									\
+    __typeof ((ptr) + 0) __ptr = (ptr);					\
+    __asm ("" : "+r" (__ptr));						\
+    __ptr;								\
+  })
+
+#endif
diff --git a/sysdeps/aarch64/fpu/vecmath_config.h b/sysdeps/aarch64/fpu/vecmath_config.h
index b75f09e5f14..55606411874 100644
--- a/sysdeps/aarch64/fpu/vecmath_config.h
+++ b/sysdeps/aarch64/fpu/vecmath_config.h
@@ -20,15 +20,7 @@
 #define _VECMATH_CONFIG_H
 
 #include <math_private.h>
-
-/* Return ptr but hide its value from the compiler so accesses through it
-   cannot be optimized based on the contents.  */
-#define ptr_barrier(ptr)                                                      \
-  ({                                                                          \
-    __typeof (ptr) __ptr = (ptr);                                             \
-    __asm("" : "+r"(__ptr));                                                  \
-    __ptr;                                                                    \
-  })
+#include <math-ptr-barrier.h>
 
 #define V_LOG_POLY_ORDER 6
 #define V_LOG_TABLE_BITS 7
diff --git a/sysdeps/generic/math-ptr-barrier.h b/sysdeps/generic/math-ptr-barrier.h
new file mode 100644
index 00000000000..ffb863cb303
--- /dev/null
+++ b/sysdeps/generic/math-ptr-barrier.h
@@ -0,0 +1,24 @@
+/* Barrier for hiding the address of constant data from the compiler.
+   Copyright (C) 2026 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _MATH_PTR_BARRIER_H
+#define _MATH_PTR_BARRIER_H	1
+
+#define ptr_barrier(ptr) ((ptr) + 0)
+
+#endif /* math-ptr-barrier.h */
diff --git a/sysdeps/ieee754/dbl-64/math_config.h b/sysdeps/ieee754/dbl-64/math_config.h
index 6a1f3062f84..d77c39da226 100644
--- a/sysdeps/ieee754/dbl-64/math_config.h
+++ b/sysdeps/ieee754/dbl-64/math_config.h
@@ -21,6 +21,7 @@
 
 #include <math.h>
 #include <math_private.h>
+#include <math-ptr-barrier.h>
 #include <nan-high-order-bit.h>
 #include <stdint.h>
 #include <stdbit.h>
diff --git a/sysdeps/ieee754/flt-32/math_config.h b/sysdeps/ieee754/flt-32/math_config.h
index 1509c2ef626..781e6c57623 100644
--- a/sysdeps/ieee754/flt-32/math_config.h
+++ b/sysdeps/ieee754/flt-32/math_config.h
@@ -21,6 +21,7 @@
 
 #include <math.h>
 #include <math_private.h>
+#include <math-ptr-barrier.h>
 #include <nan-high-order-bit.h>
 #include <stdint.h>
 #include <stdbit.h>
-- 
2.53.0



More information about the Libc-alpha mailing list