https://gcc.gnu.org/g:4fb8b2a1fcd8ac89a51eba07f76e8e1af1d215c7

commit r16-7065-g4fb8b2a1fcd8ac89a51eba07f76e8e1af1d215c7
Author: Wilco Dijkstra <[email protected]>
Date:   Mon Jan 26 14:11:17 2026 +0000

    AArch64: Block symbols in literal pools [PR 123791]
    
    Symbols with a large offset may be emitted into a literal pool.
    aarch64_select_rtx_section() may then select .text or .rodata even if
    the symbol has a dynamic relocation.  Checking for CONST_INT or
    CONST_DOUBLE avoids this.  Ensure aarch64_cannot_force_const_mem()
    returns true for symbols and labels so that they cannot be placed in
    literal pools.  Only the large code model emits symbols in the literal
    pool (no support for PIC/PIE).
    
    gcc:
            PR target/123791
            * config/aarch64/aarch64.cc (aarch64_cannot_force_const_mem):
            Always return true for symbols and labels except for large model.
            (aarch64_select_rtx_section): Force .rodata for constants only.
    
    gcc/testsuite:
            PR target/123791
            * gcc.target/aarch64/pr123791.c: New test.

Diff:
---
 gcc/config/aarch64/aarch64.cc               | 20 ++++++++------------
 gcc/testsuite/gcc.target/aarch64/pr123791.c | 10 ++++++++++
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index e443dce6644e..071273957909 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -11145,19 +11145,12 @@ aarch64_cannot_force_const_mem (machine_mode mode 
ATTRIBUTE_UNUSED, rtx x)
        || aarch64_sme_vq_unspec_p (x, &factor))
       return true;
 
+  /* Only allow symbols in literal pools with the large model (non-PIC).  */
   poly_int64 offset;
   rtx base = strip_offset_and_salt (x, &offset);
-  if (SYMBOL_REF_P (base) || LABEL_REF_P (base))
-    {
-      /* We checked for POLY_INT_CST offsets above.  */
-      if (aarch64_classify_symbol (base, offset.to_constant ())
-         != SYMBOL_FORCE_TO_MEM)
-       return true;
-      else
-       /* Avoid generating a 64-bit relocation in ILP32; leave
-          to aarch64_expand_mov_immediate to handle it properly.  */
-       return mode != ptr_mode;
-    }
+  if ((SYMBOL_REF_P (base) || LABEL_REF_P (base))
+      && aarch64_cmodel != AARCH64_CMODEL_LARGE)
+    return true;
 
   return aarch64_tls_referenced_p (x);
 }
@@ -14312,11 +14305,14 @@ aarch64_select_rtx_section (machine_mode mode,
                            rtx x,
                            unsigned HOST_WIDE_INT align)
 {
+  /* Forcing special symbols into the .text section is not correct (PR123791).
+     This is only an issue with the large code model.  */
   if (aarch64_can_use_per_function_literal_pools_p ())
     return function_section (current_function_decl);
 
   /* When using anchors for constants use the readonly section.  */
-  if (known_le (GET_MODE_SIZE (mode), 8))
+  if ((CONST_INT_P (x) || CONST_DOUBLE_P (x))
+      && known_le (GET_MODE_SIZE (mode), 8))
     return readonly_data_section;
 
   return default_elf_select_rtx_section (mode, x, align);
diff --git a/gcc/testsuite/gcc.target/aarch64/pr123791.c 
b/gcc/testsuite/gcc.target/aarch64/pr123791.c
new file mode 100644
index 000000000000..afdf37e8aac1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr123791.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mpc-relative-literal-loads" } */
+
+char *
+foo ()
+{
+  return (char *) (__UINTPTR_TYPE__) foo + 7483647;
+}
+
+/* { dg-final { scan-assembler-not "\\.(word|xword)\tfoo" { xfail 
aarch64_large } } } */

Reply via email to