[gcc(refs/users/meissner/heads/work251-dmf)] DMF patch 3

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

commit ced10b37b1dc1c7355f98067cf6545e552c9fe29
Author: Michael Meissner <[email protected]>
Date:   Sat Jul 18 02:32:31 2026 -0400

    DMF patch 3
    
    The changes have been bootstrapped and regression tested on
    powerpc64le-linux.
    
    Register __dmr1024 as a new 1024-bit opaque built-in type, following
    the same pattern as the existing __vector_pair (OOmode) and
    __vector_quad (XOmode) opaque types.  __dmr1024 uses TDOmode, which
    was already added in a previous commit ("rs6000: Add TDOmode
    support"), and is intended to hold the contents of a Dense Math
    Register (DMR) when the Dense Math Facility (-mdense-math) is
    enabled.
    
    Note there is no __dmr1024 move pattern (movtdo) yet, so none of
    these tests perform an actual load/store/copy of a __dmr1024 value;
    that is left for a follow-on patch that adds the Dense Math move
    support.
    
    2026-07-13  Manjunath Matti  <[email protected]>
    
    gcc/
    
            * config/rs6000/rs6000.h (RS6000_BTI_dmr1024): New enumerator.
            (RS6000_BTI_ptr_dmr1024): New enumerator.
            (dmr1024_type_node): New macro.
            (ptr_dmr1024_type_node): New macro.
            * config/rs6000/rs6000-builtin.cc (rs6000_type_string): Handle
            dmr1024_type_node.
            (rs6000_init_builtins): Register the __dmr1024 opaque type and
            its pointer-to-const variant, with 512-bit alignment.
            * config/rs6000/rs6000.cc (rs6000_mangle_type): Handle
            dmr1024_type_node.
            (rs6000_invalid_conversion): Reject conversions to/from TDOmode.
            (rs6000_opaque_type_invalid_use_p): Gate __vector_quad and
            __vector_pair on TARGET_MMA and __dmr1024 on TARGET_DMF
            independently, and require -mdense-math for __dmr1024.
    
    gcc/testsuite/
    
            * gcc.target/powerpc/dmr1024-alignment.c: New test case.
            * gcc.target/powerpc/dmr1024-compile.c: Likewise.
            * gcc/testsuite/gcc.target/powerpc/dmr1024-invalid-use-1.c: Likewise.
            * gcc/testsuite/gcc.target/powerpc/dmr1024-invalid-use-2.c: Likewise.
            * gcc/testsuite/gcc.target/powerpc/dmf-no-mma.c: Likewise.

Diff:
---
 gcc/config/rs6000/rs6000-builtin.cc                | 17 ++++++++
 gcc/config/rs6000/rs6000.cc                        | 46 +++++++++++++++-------
 gcc/config/rs6000/rs6000.h                         |  4 ++
 gcc/testsuite/gcc.target/powerpc/dmf-no-mma.c      | 19 +++++++++
 .../gcc.target/powerpc/dmr1024-alignment.c         | 33 ++++++++++++++++
 gcc/testsuite/gcc.target/powerpc/dmr1024-compile.c | 46 ++++++++++++++++++++++
 .../gcc.target/powerpc/dmr1024-invalid-use-1.c     | 32 +++++++++++++++
 .../gcc.target/powerpc/dmr1024-invalid-use-2.c     | 23 +++++++++++
 8 files changed, 206 insertions(+), 14 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
index 2d35d5861246..cea668fb163c 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -517,6 +517,8 @@ const char *rs6000_type_string (tree type_node)
     return "__vector_pair";
   else if (type_node == vector_quad_type_node)
     return "__vector_quad";
+  else if (type_node == dmr1024_type_node)
+    return "__dmr1024";
 
   return "unknown";
 }
@@ -818,6 +820,21 @@ rs6000_init_builtins (void)
   t = build_qualified_type (vector_quad_type_node, TYPE_QUAL_CONST);
   ptr_vector_quad_type_node = build_pointer_type (t);
 
+  /* For TDOmode (1024-bit dense math registers), don't use an alignment
+     of 1024, use 512.  TDOmode loads and stores are always broken up
+     into two vector pair loads or stores.  In addition, we don't have
+     support for aligning the stack to 1024 bits.  */
+  dmr1024_type_node = make_node (OPAQUE_TYPE);
+  SET_TYPE_MODE (dmr1024_type_node, TDOmode);
+  TYPE_SIZE (dmr1024_type_node) = bitsize_int (GET_MODE_BITSIZE (TDOmode));
+  TYPE_PRECISION (dmr1024_type_node) = GET_MODE_BITSIZE (TDOmode);
+  TYPE_SIZE_UNIT (dmr1024_type_node) = size_int (GET_MODE_SIZE (TDOmode));
+  SET_TYPE_ALIGN (dmr1024_type_node, 512);
+  TYPE_USER_ALIGN (dmr1024_type_node) = 0;
+  lang_hooks.types.register_builtin_type (dmr1024_type_node, "__dmr1024");
+  t = build_qualified_type (dmr1024_type_node, TYPE_QUAL_CONST);
+  ptr_dmr1024_type_node = build_pointer_type (t);
+
   tdecl = add_builtin_type ("__bool char", bool_char_type_node);
   TYPE_NAME (bool_char_type_node) = tdecl;
 
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 64683102e9e6..31c8f9149668 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -20670,6 +20670,8 @@ rs6000_mangle_type (const_tree type)
     return "u13__vector_pair";
   if (type == vector_quad_type_node)
     return "u13__vector_quad";
+  if (type == dmr1024_type_node)
+    return "u9__dmr1024";
 
   /* For all other types, use the default mangling.  */
   return NULL;
@@ -28840,7 +28842,8 @@ rs6000_invalid_conversion (const_tree fromtype, const_tree totype)
 
   if (frommode != tomode)
     {
-      /* Do not allow conversions to/from XOmode and OOmode types.  */
+      /* Do not allow conversions to/from XOmode, OOmode and TDOmode
+	 types.  */
       if (frommode == XOmode)
 	return N_("invalid conversion from type %<__vector_quad%>");
       if (tomode == XOmode)
@@ -28849,6 +28852,10 @@ rs6000_invalid_conversion (const_tree fromtype, const_tree totype)
 	return N_("invalid conversion from type %<__vector_pair%>");
       if (tomode == OOmode)
 	return N_("invalid conversion to type %<__vector_pair%>");
+      if (frommode == TDOmode)
+	return N_("invalid conversion from type %<__dmr1024%>");
+      if (tomode == TDOmode)
+	return N_("invalid conversion to type %<__dmr1024%>");
     }
 
   /* Conversion allowed.  */
@@ -29330,33 +29337,44 @@ constant_generates_xxspltidp (vec_const_128bit_type *vsx_const)
   return sf_value;
 }
 
-/* Now we have only two opaque types, they are __vector_quad and
-   __vector_pair built-in types.  They are target specific and
-   only available when MMA is supported.  With MMA supported, it
-   simply returns true, otherwise it checks if the given gimple
-   STMT is an assignment, asm or call stmt and uses either of
-   these two opaque types unexpectedly, if yes, it would raise
-   an error message and returns true, otherwise it returns false.  */
+/* Now we have three opaque types: the __vector_quad, __vector_pair and
+   __dmr1024 built-in types.  They are target specific and each one is
+   only available when its required ISA support is enabled:
+   __vector_pair requires MMA or DMF (vector pairs are used by both),
+   __vector_quad requires MMA, and __dmr1024 requires DMF.  Note that
+   DMF does not imply MMA (e.g. -mcpu=future -mno-mma).  With both MMA
+   and DMF enabled, all three types are usable and this simply returns
+   false, otherwise it checks if the given gimple STMT is an
+   assignment, asm or call stmt and uses one of these opaque types
+   whose ISA support is missing, if yes, it would raise an error
+   message and returns true, otherwise it returns false.  */
 
 bool
 rs6000_opaque_type_invalid_use_p (gimple *stmt)
 {
-  if (TARGET_MMA)
+  if (TARGET_MMA && TARGET_DMF)
     return false;
 
-  /* If the given TYPE is one MMA opaque type, emit the corresponding
-     error messages and return true, otherwise return false.  */
+  /* If the given TYPE is one MMA/DMF opaque type whose required ISA
+     support is missing, emit the corresponding error message and
+     return true, otherwise return false.  */
   auto check_and_error_invalid_use = [](tree type)
   {
     tree mv = TYPE_MAIN_VARIANT (type);
-    if (mv == vector_quad_type_node)
+    if (!TARGET_MMA && mv == vector_quad_type_node)
       {
 	error ("type %<__vector_quad%> requires the %qs option", "-mmma");
 	return true;
       }
-    else if (mv == vector_pair_type_node)
+    else if (!TARGET_MMA && !TARGET_DMF && mv == vector_pair_type_node)
+      {
+	error ("type %<__vector_pair%> requires the %qs or %qs option", "-mmma"
+	       , "-mdense-math");
+	return true;
+      }
+    else if (!TARGET_DMF && mv == dmr1024_type_node)
       {
-	error ("type %<__vector_pair%> requires the %qs option", "-mmma");
+	error ("type %<__dmr1024%> requires the %qs option", "-mdense-math");
 	return true;
       }
     return false;
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 8235e095bcce..5afca1bfb489 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2247,6 +2247,7 @@ enum rs6000_builtin_type_index
   RS6000_BTI_const_str,		 /* pointer to const char * */
   RS6000_BTI_vector_pair,	 /* unsigned 256-bit types (vector pair).  */
   RS6000_BTI_vector_quad,	 /* unsigned 512-bit types (vector quad).  */
+  RS6000_BTI_dmr1024,            /* unsigned 1024-bit type (dmr1024).  */
   RS6000_BTI_const_ptr_void,     /* const pointer to void */
   RS6000_BTI_ptr_V16QI,
   RS6000_BTI_ptr_V1TI,
@@ -2285,6 +2286,7 @@ enum rs6000_builtin_type_index
   RS6000_BTI_ptr_dfloat128,
   RS6000_BTI_ptr_vector_pair,
   RS6000_BTI_ptr_vector_quad,
+  RS6000_BTI_ptr_dmr1024,
   RS6000_BTI_ptr_long_long,
   RS6000_BTI_ptr_long_long_unsigned,
   RS6000_BTI_INTPTI,
@@ -2346,6 +2348,7 @@ enum rs6000_builtin_type_index
 #define const_str_type_node		 (rs6000_builtin_types[RS6000_BTI_const_str])
 #define vector_pair_type_node		 (rs6000_builtin_types[RS6000_BTI_vector_pair])
 #define vector_quad_type_node		 (rs6000_builtin_types[RS6000_BTI_vector_quad])
+#define dmr1024_type_node                (rs6000_builtin_types[RS6000_BTI_dmr1024])
 #define pcvoid_type_node		 (rs6000_builtin_types[RS6000_BTI_const_ptr_void])
 #define ptr_V16QI_type_node		 (rs6000_builtin_types[RS6000_BTI_ptr_V16QI])
 #define ptr_V1TI_type_node		 (rs6000_builtin_types[RS6000_BTI_ptr_V1TI])
@@ -2384,6 +2387,7 @@ enum rs6000_builtin_type_index
 #define ptr_dfloat128_type_node		 (rs6000_builtin_types[RS6000_BTI_ptr_dfloat128])
 #define ptr_vector_pair_type_node	 (rs6000_builtin_types[RS6000_BTI_ptr_vector_pair])
 #define ptr_vector_quad_type_node	 (rs6000_builtin_types[RS6000_BTI_ptr_vector_quad])
+#define ptr_dmr1024_type_node            (rs6000_builtin_types[RS6000_BTI_ptr_dmr1024])
 #define ptr_long_long_integer_type_node	 (rs6000_builtin_types[RS6000_BTI_ptr_long_long])
 #define ptr_long_long_unsigned_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_long_unsigned])
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dmf-no-mma.c b/gcc/testsuite/gcc.target/powerpc/dmf-no-mma.c
new file mode 100644
index 000000000000..3da0c8c601ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dmf-no-mma.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_future_compile_ok } */
+/* { dg-options "-mdejagnu-cpu=future -mdense-math -mno-mma -O2" } */
+
+/* Dense Math (-mdense-math) without MMA supports __vector_pair and
+   __dmr1024 (see dmf-no-mma-1.c), but __vector_quad moves still
+   require MMA.  Verify that a __vector_quad copy under -mno-mma is
+   diagnosed with a proper error message via the movxo expander
+   instead of ICEing.  The error is emitted during RTL expansion, so
+   its reported location can be fragile; match it anywhere in the
+   output.  */
+
+void
+copy_quad (__vector_quad *dst, __vector_quad *src)
+{
+  *dst = *src;
+}
+
+/* { dg-error "type '__vector_quad' requires the '-mmma' option" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/powerpc/dmr1024-alignment.c b/gcc/testsuite/gcc.target/powerpc/dmr1024-alignment.c
new file mode 100644
index 000000000000..147556c90e01
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dmr1024-alignment.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hard_float } */
+/* { dg-options "-O2 -mhard-float" } */
+
+/* Verify the __dmr1024 opaque type is always registered (regardless of
+   whether -mdense-math is enabled) and has the expected size and
+   alignment, following the same model as __vector_pair and
+   __vector_quad in mma-alignment.c.  */
+
+#include <stdlib.h>
+
+struct
+{
+  int __attribute__ ((__aligned__)) ivar;
+  __dmr1024 dmr;
+} s;
+
+int
+main (void)
+{
+  /* __dmr1024 holds the contents of a 1,024-bit Dense Math Register.  */
+  if (sizeof (__dmr1024) != 128)
+    abort ();
+
+  /* __dmr1024 loads/stores are always broken into two vector-pair
+     transfers, and there is no support for aligning the stack to
+     1,024 bits, so the type alignment is 512 bits (64 bytes), matching
+     __vector_quad rather than its own 1,024-bit size.  */
+  if (__alignof__ (s.dmr) != 64)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/dmr1024-compile.c b/gcc/testsuite/gcc.target/powerpc/dmr1024-compile.c
new file mode 100644
index 000000000000..2ae66738f026
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dmr1024-compile.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_future_compile_ok } */
+/* { dg-options "-mdejagnu-cpu=future -mdense-math -O2" } */
+
+/* Verify that __dmr1024 is accepted as a type with the expected size
+   and alignment, and that it can be used through pointers without
+   triggering any diagnostics.  Only pointers are passed around here;
+   actual __dmr1024 value copies are covered by dmr1024-copy.c.  */
+
+typedef __dmr1024 dmr_t;
+
+_Static_assert (sizeof (__dmr1024) == 128, "__dmr1024 must be 128 bytes");
+_Static_assert (__alignof__ (__dmr1024) == 64,
+		 "__dmr1024 alignment must be 64 bytes");
+
+struct dmr_holder
+{
+  __dmr1024 dmr;
+};
+
+extern __dmr1024 global_dmr;
+extern const dmr_t *global_dmr_ptr;
+
+__dmr1024 *
+identity (__dmr1024 *p)
+{
+  return p;
+}
+
+const dmr_t *
+identity_const (const dmr_t *p)
+{
+  return p;
+}
+
+void *
+as_void_ptr (__dmr1024 *p)
+{
+  return (void *) p;
+}
+
+__dmr1024 *
+holder_dmr (struct dmr_holder *h)
+{
+  return &h->dmr;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/dmr1024-invalid-use-1.c b/gcc/testsuite/gcc.target/powerpc/dmr1024-invalid-use-1.c
new file mode 100644
index 000000000000..dfd72bded7a3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dmr1024-invalid-use-1.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_future_compile_ok } */
+/* { dg-options "-mdejagnu-cpu=future -mdense-math -O2 -std=gnu17" } */
+
+/* The __dmr1024 opaque type, like __vector_quad and __vector_pair
+   (see pr96506-1.c), may not be used as a function parameter.  Verify
+   we flag errors on these uses rather than ICE.
+
+   This must be kept separate from the return-value test
+   (dmr1024-invalid-use-2.c): the parameter diagnostics below are only
+   emitted during RTL expansion, which is skipped entirely once a
+   parse-time error (such as the return-value diagnostic) has been
+   emitted.  */
+
+extern void bar0 ();
+extern void bar1 ();
+
+typedef __dmr1024 dmr_t;
+
+void
+foo0 (void)
+{
+  __dmr1024 v;
+  bar0 (v); /* { dg-error "invalid use of Dense Math operand of type .__dmr1024. as a function parameter" } */
+}
+
+void
+foo1 (void)
+{
+  dmr_t v;
+  bar1 (v); /* { dg-error "invalid use of Dense Math operand of type .__dmr1024. as a function parameter" } */
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/dmr1024-invalid-use-2.c b/gcc/testsuite/gcc.target/powerpc/dmr1024-invalid-use-2.c
new file mode 100644
index 000000000000..c814cf78827e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dmr1024-invalid-use-2.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_future_compile_ok } */
+/* { dg-options "-mdejagnu-cpu=future -mdense-math -O2" } */
+
+/* The __dmr1024 opaque type, like __vector_quad and __vector_pair
+   (see pr96506-2.c), may not be used as a function return value.
+   Verify we flag errors on these uses rather than ICE.  Kept separate
+   from the function-parameter test (dmr1024-invalid-use-1.c); see the
+   comment there.  */
+
+typedef __dmr1024 dmr_t;
+
+__dmr1024
+foo0 (__dmr1024 *src)
+{ /* { dg-error "invalid use of Dense Math type .__dmr1024. as a function return value" } */
+  return *src;
+}
+
+dmr_t
+foo1 (dmr_t *src)
+{ /* { dg-error "invalid use of Dense Math type .__dmr1024. as a function return value" } */
+  return *src;
+}
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.