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 committed all of the patches in my backlog (dense math registers, other
-mcpu=future instructions, random bug fixes, support for _Float16 and
__bfloat16, and optimizations for vector logical operations on power10/power11)
into the IBM vendor branch:
vendors/ibm/gcc-17-future
2026-07-01 Michael Meissner <[email protected]>
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 1af71030368..c892930a8a9 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 afe5d45c125..5178fcbba70 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -4358,12 +4358,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;
}
@@ -21360,7 +21363,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.54.0
--
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: [email protected]