[gcc r15-11374] rs6000: Fix PTImode attribute handling [PR106895]

jeevitha via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:92bd6918a1892d36a5ad51d4be12f004cc20d931

commit r15-11374-g92bd6918a1892d36a5ad51d4be12f004cc20d931
Author: Jeevitha <[email protected]>
Date:   Wed Jul 15 11:51:24 2026 -0500

    rs6000: Fix PTImode attribute handling [PR106895]
    
    PTImode is used to generate even/odd register pairs for 128-bit values.
    When PTImode is specified via a type attribute, compilation fails
    because no internal type exists to represent this mode.
    
    Introduce signed and unsigned PTImode internal builtin types to handle
    PTImode. These __pti_internal types are not documented, as they are not
    intended for direct user use.
    
    2026-06-04  Jeevitha Palanisamy  <[email protected]>
    
    gcc/
            PR target/106895
            * config/rs6000/rs6000.h (enum rs6000_builtin_type_index): Add
            RS6000_BTI_INTPTI and RS6000_BTI_UINTPTI.
            (intPTI_type_internal_node, uintPTI_type_internal_node): New
            PTImode type macros.
            * config/rs6000/rs6000-builtin.cc (rs6000_init_builtins): Register
            signed and unsigned PTImode internal builtin types.
            * config/rs6000/sync.md (trunctipti2): New splitter.
            (extendptiti2): Likewise.
            (zero_extendptiti2): Likewise.
    
    gcc/testsuite/
            PR target/106895
            * gcc.target/powerpc/pr106895-1.c: New test.
            * gcc.target/powerpc/pr106895-2.c: New test.
    
    (cherry picked from commit b7385d51c8170c75b285b0a317884b51d4012e5a)

Diff:
---
 gcc/config/rs6000/rs6000-builtin.cc           | 15 ++++++++
 gcc/config/rs6000/rs6000.h                    |  4 +++
 gcc/config/rs6000/sync.md                     | 51 +++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/powerpc/pr106895-1.c | 16 +++++++++
 gcc/testsuite/gcc.target/powerpc/pr106895-2.c | 24 +++++++++++++
 5 files changed, 110 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
index b111691fc475..658757857fb7 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -756,6 +756,21 @@ rs6000_init_builtins (void)
   else
     ieee128_float_type_node = NULL_TREE;
 
+  /* PTImode to get even/odd register pairs.  */
+  if (TARGET_POWERPC64)
+    {
+      intPTI_type_internal_node = make_signed_type (GET_MODE_BITSIZE (PTImode));
+      SET_TYPE_MODE (intPTI_type_internal_node, PTImode);
+      t = build_qualified_type (intPTI_type_internal_node, TYPE_QUAL_CONST);
+      lang_hooks.types.register_builtin_type (intPTI_type_internal_node,
+					      "__pti_internal");
+
+      uintPTI_type_internal_node = make_unsigned_type (GET_MODE_BITSIZE (PTImode));
+      SET_TYPE_MODE (uintPTI_type_internal_node, PTImode);
+      t = build_qualified_type (uintPTI_type_internal_node, TYPE_QUAL_CONST);
+      lang_hooks.types.register_builtin_type (uintPTI_type_internal_node,
+					      "__upti_internal");
+    }
   /* Vector pair and vector quad support.  */
   vector_pair_type_node = make_node (OPAQUE_TYPE);
   SET_TYPE_MODE (vector_pair_type_node, OOmode);
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index e18d24d1317b..d66a46ff0914 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2289,6 +2289,8 @@ enum rs6000_builtin_type_index
   RS6000_BTI_ptr_vector_quad,
   RS6000_BTI_ptr_long_long,
   RS6000_BTI_ptr_long_long_unsigned,
+  RS6000_BTI_INTPTI,
+  RS6000_BTI_UINTPTI,
   RS6000_BTI_MAX
 };
 
@@ -2333,6 +2335,8 @@ enum rs6000_builtin_type_index
 #define uintDI_type_internal_node	 (rs6000_builtin_types[RS6000_BTI_UINTDI])
 #define intTI_type_internal_node	 (rs6000_builtin_types[RS6000_BTI_INTTI])
 #define uintTI_type_internal_node	 (rs6000_builtin_types[RS6000_BTI_UINTTI])
+#define intPTI_type_internal_node	 (rs6000_builtin_types[RS6000_BTI_INTPTI])
+#define uintPTI_type_internal_node	 (rs6000_builtin_types[RS6000_BTI_UINTPTI])
 #define float_type_internal_node	 (rs6000_builtin_types[RS6000_BTI_float])
 #define double_type_internal_node	 (rs6000_builtin_types[RS6000_BTI_double])
 #define long_double_type_internal_node	 (rs6000_builtin_types[RS6000_BTI_long_double])
diff --git a/gcc/config/rs6000/sync.md b/gcc/config/rs6000/sync.md
index e42cf9e9506c..656b8fb22378 100644
--- a/gcc/config/rs6000/sync.md
+++ b/gcc/config/rs6000/sync.md
@@ -198,6 +198,57 @@
   DONE;
 })
 
+;; PTI and TI are both 128-bit modes; the following conversions are
+;; register-class changes only, no actual truncation, sign or zero
+;; extension occurs.
+(define_insn_and_split "trunctipti2"
+  [(set (match_operand:PTI 0 "register_operand" "=r,r")
+        (truncate:PTI (match_operand:TI 1 "register_operand" "0,r")))]
+  "TARGET_POWERPC64"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 2) (match_dup 4))
+   (set (match_dup 3) (match_dup 5))]
+{
+  operands[2] = gen_lowpart (DImode, operands[0]);
+  operands[3] = gen_highpart (DImode, operands[0]);
+  operands[4] = gen_lowpart (DImode, operands[1]);
+  operands[5] = gen_highpart (DImode, operands[1]);
+}
+[(set_attr "length" "0,8")])
+
+(define_insn_and_split "extendptiti2"
+  [(set (match_operand:TI 0 "register_operand" "=r,r")
+        (sign_extend:TI (match_operand:PTI 1 "register_operand" "0,r")))]
+  "TARGET_POWERPC64"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 2) (match_dup 4))
+   (set (match_dup 3) (match_dup 5))]
+{
+  operands[2] = gen_lowpart (DImode, operands[0]);
+  operands[3] = gen_highpart (DImode, operands[0]);
+  operands[4] = gen_lowpart (DImode, operands[1]);
+  operands[5] = gen_highpart (DImode, operands[1]);
+}
+[(set_attr "length" "0,8")])
+
+(define_insn_and_split "zero_extendptiti2"
+  [(set (match_operand:TI 0 "register_operand" "=r,r")
+        (zero_extend:TI (match_operand:PTI 1 "register_operand" "0,r")))]
+  "TARGET_POWERPC64"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 2) (match_dup 4))
+   (set (match_dup 3) (match_dup 5))]
+{
+  operands[2] = gen_lowpart (DImode, operands[0]);
+  operands[3] = gen_highpart (DImode, operands[0]);
+  operands[4] = gen_lowpart (DImode, operands[1]);
+  operands[5] = gen_highpart (DImode, operands[1]);
+}
+[(set_attr "length" "0,8")])
+
 ;; If TARGET_PREFIXED, always use pstq rather than stq.
 (define_insn "store_quadpti"
   [(set (match_operand:PTI 0 "quad_memory_operand" "=wQ")
diff --git a/gcc/testsuite/gcc.target/powerpc/pr106895-1.c b/gcc/testsuite/gcc.target/powerpc/pr106895-1.c
new file mode 100644
index 000000000000..dfcafcd57e7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr106895-1.c
@@ -0,0 +1,16 @@
+/* PR target/106895 */
+/* { dg-do assemble } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O2 -save-temps" } */
+
+/* Verify the following generates even/odd register pairs.  */
+
+typedef __int128 pti __attribute__((mode(PTI)));
+
+void
+set128 (pti val, pti *mem)
+{
+  asm ("stq %1,%0" : "=m" (*mem) : "r" (val));
+}
+
+/* { dg-final { scan-assembler {\mstq\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr106895-2.c b/gcc/testsuite/gcc.target/powerpc/pr106895-2.c
new file mode 100644
index 000000000000..db8e29c67061
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr106895-2.c
@@ -0,0 +1,24 @@
+/* PR target/106895 */
+/* { dg-do run } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O2" } */
+
+#include <stdlib.h>
+
+typedef __int128 ti;
+typedef __int128 pti __attribute__((mode(PTI)));
+
+volatile ti  a = 140;
+volatile pti b;
+volatile ti  c;
+
+int main(void)
+{
+  b = (pti) a;
+  c = (ti) b;
+
+  if (c != a)
+    abort();
+
+  return 0;
+}
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.