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. I have tested this patch on both little endian and big endian PowerPC servers with no regressions. In addition, I have build a compiler on a power10 system with power10 code generation using BOOT_CLFAGS='-g -O2 -mcmodel=large' to make sure there were no regressions. Can I check this patch into the master GCC branch? After an appropriate burn-in time, can I check this patch into the active branches also? 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. --- 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(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr120681.c diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h index 0316d8cb65d..cf60ff14e10 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 80fc500fcec..d0e92f2f789 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 00000000000..d883d1c8a95 --- /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} } } */ -- 2.49.0 -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com