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 } } } */
