[gcc(refs/users/meissner/heads/work252-bugs)] PR target/120681 - allow -mcmodel=large with PC relative addressing

Michael Meissner via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:16c19adea8fbf54ff013c7e1996df7e299f9cd20

commit 16c19adea8fbf54ff013c7e1996df7e299f9cd20
Author: Michael Meissner <[email protected]>
Date:   Fri Jul 24 00:28:31 2026 -0400

    PR target/120681 - allow -mcmodel=large with PC relative 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.
    
    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-24  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.

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 1af710303687..c892930a8a93 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 c620d1a31e87..757a807b726f 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -4426,12 +4426,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;
     }
@@ -21528,7 +21531,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}     } } */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.