]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000: Add the __dmr1024 opaque type.
authorManjunath S Matti <mmatti@linux.ibm.com>
Wed, 22 Jul 2026 14:07:32 +0000 (09:07 -0500)
committerJeevitha <jeevitha@linux.ibm.com>
Thu, 23 Jul 2026 05:26:48 +0000 (00:26 -0500)
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.

2026-07-22  Manjunath Matti  <mmatti@linux.ibm.com>

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.target/powerpc/dmr1024-invalid-use-1.c: Likewise.
* gcc.target/powerpc/dmr1024-invalid-use-2.c: Likewise.
* gcc.target/powerpc/dmf-no-mma.c: Likewise.

gcc/config/rs6000/rs6000-builtin.cc
gcc/config/rs6000/rs6000.cc
gcc/config/rs6000/rs6000.h
gcc/testsuite/gcc.target/powerpc/dmf-no-mma.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/dmr1024-alignment.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/dmr1024-compile.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/dmr1024-invalid-use-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/dmr1024-invalid-use-2.c [new file with mode: 0644]

index 806505220f291a3e129dc33d8f0745ed9f15a722..4ecbbe43ba00349dbf369a34217988e57956a18c 100644 (file)
@@ -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;
 
index 8a0f52fd410e8d450462e6aca7596325d6138e19..6ff877dac6c1af3e56e41ff9ca269f31b5f12ffc 100644 (file)
@@ -20792,6 +20792,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;
@@ -29015,7 +29017,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)
@@ -29024,6 +29027,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.  */
@@ -29505,33 +29512,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;
index 420ab45af63874fe8c94eb1b9343651f22c67032..bcd4c39d24dca883d3107a5c5aa61f04687429f0 100644 (file)
@@ -2276,6 +2276,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,
@@ -2314,6 +2315,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,
@@ -2375,6 +2377,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])
@@ -2413,6 +2416,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 (file)
index 0000000..3da0c8c
--- /dev/null
@@ -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 (file)
index 0000000..147556c
--- /dev/null
@@ -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 (file)
index 0000000..2ae6673
--- /dev/null
@@ -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 (file)
index 0000000..dfd72bd
--- /dev/null
@@ -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 (file)
index 0000000..c814cf7
--- /dev/null
@@ -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;
+}