https://gcc.gnu.org/g:a61ace2f50af36ca1a687b911e807e85bef528c5
commit a61ace2f50af36ca1a687b911e807e85bef528c5 Author: Michael Meissner <meiss...@linux.ibm.com> Date: Tue Jun 17 12:13:05 2025 -0400 PR target/120681 - allow -mcmodel=large with prefixed addressing When I implemented the pc-relative support for power10 in GCC, I disabled using pc-relative support for -mcmodel=large. At the time, I didn't want to dig into the issues. It is now time to allow -mcmodel=large to generate pc-relative code. This patch allows -mcmodel=large to use prefixed addressing on power10, power11, and possibly other future PowerPC processors in addition to the current -mcmodel=medium support. 2025-06-17 Michael Meissner <meiss...@linux.ibm.com> gcc/ PR target/120681 * config/rs6000/linux64.h (PCREL_SUPPORTED_BY_OS): Allow large code model as well as medium code model. * config/rs6000/rs6000.cc (rs6000_option_override_internal): Likewise. (rs6000_elf_declare_function_name): Don't create the local/non-local labels for large code model if we are using PC-relative addressing. gcc/testsuite/ PR target/120681 * gcc.target/powerpc/pr120681.c: New test. Diff: --- gcc/config/rs6000/linux64.h | 5 +++-- gcc/config/rs6000/rs6000.cc | 13 ++++++----- gcc/testsuite/gcc.target/powerpc/pr120681.c | 34 +++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h index 0316d8cb65da..cf60ff14e108 100644 --- a/gcc/config/rs6000/linux64.h +++ b/gcc/config/rs6000/linux64.h @@ -564,7 +564,8 @@ extern int dot_symbols; /* Enable using prefixed PC-relative addressing on POWER10 if the ABI supports it. The ELF v2 ABI only supports PC-relative relocations for - the medium code model. */ + the medium/large code models. */ #define PCREL_SUPPORTED_BY_OS (TARGET_POWER10 && TARGET_PREFIXED \ && ELFv2_ABI_CHECK \ - && TARGET_CMODEL == CMODEL_MEDIUM) + && (TARGET_CMODEL == CMODEL_MEDIUM \ + || TARGET_CMODEL == CMODEL_LARGE)) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 80fc500fcec8..d0e92f2f7898 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -4360,12 +4360,15 @@ rs6000_option_override_internal (bool global_init_p) && (rs6000_isa_flags_explicit & OPTION_MASK_PCREL) == 0) rs6000_isa_flags |= OPTION_MASK_PCREL; - /* -mpcrel requires -mcmodel=medium, but we can't check TARGET_CMODEL until - after the subtarget override options are done. */ - else if (TARGET_PCREL && TARGET_CMODEL != CMODEL_MEDIUM) + /* -mpcrel requires medium or large code models, but we can't check + TARGET_CMODEL until after the subtarget override options are done. */ + else if (TARGET_PCREL + && TARGET_CMODEL != CMODEL_MEDIUM + && TARGET_CMODEL != CMODEL_LARGE) { if ((rs6000_isa_flags_explicit & OPTION_MASK_PCREL) != 0) - error ("%qs requires %qs", "-mpcrel", "-mcmodel=medium"); + error ("%qs requires %qs or %qs", "-mpcrel", "-mcmodel=medium", + "-mcmodel=large"); rs6000_isa_flags &= ~OPTION_MASK_PCREL; } @@ -21356,7 +21359,7 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl) ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function"); ASM_DECLARE_RESULT (file, DECL_RESULT (decl)); - if (TARGET_CMODEL == CMODEL_LARGE + if (TARGET_CMODEL == CMODEL_LARGE && !TARGET_PCREL && rs6000_global_entry_point_prologue_needed_p ()) { char buf[256]; diff --git a/gcc/testsuite/gcc.target/powerpc/pr120681.c b/gcc/testsuite/gcc.target/powerpc/pr120681.c new file mode 100644 index 000000000000..d883d1c8a951 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr120681.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_elfv2 } */ +/* { dg-require-effective-target powerpc_pcrel } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2 -mcmodel=large" } */ + +/* PR target/120681 -- verify that -mcpu=power10 -mcmodel=large uses PC + relative addressing instead of using TOC addressing. */ + +#ifndef TYPE +#define TYPE unsigned long +#endif + +extern TYPE global_var; + +void +set_global (TYPE value) +{ + /* + * Generate: + * pld 9,global_var@got@pcrel + * std 3,0(9) + * + * Not: + * addis 9,2,.LC0@toc@ha + * ld 9,.LC0@toc@l(9) + * std 3,0(9) + */ + + global_var = value; +} + +/* { dg-final { scan-assembler {@got@pcrel} } } */ +/* { dg-final { scan-assembler-not {@toc@ha} } } */ +/* { dg-final { scan-assembler-not {@toc@l} } } */