https://gcc.gnu.org/g:7d0d52665540cd577a18ceb683c45fff58e9f7bc
commit 7d0d52665540cd577a18ceb683c45fff58e9f7bc Author: Manjunath S Matti <[email protected]> Date: Tue Jul 7 02:27:45 2026 -0500 rs6000: Add the __dmr1024 opaque type 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. The type is given 512-bit (not 1024-bit) alignment: TDOmode loads and stores are always broken up into two vector-pair transfers, and there is no support for aligning the stack to 1024 bits. The ones already established on this branch (__dmr1024 / TARGET_DMF / DMR_REGNO_P, see commits 348f29b2949 and 6c00f166014). 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-07 Manjunath Matti <[email protected]> gcc/ChangeLog: * 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/ChangeLog: * gcc.target/powerpc/dmr1024-alignment.c: New test. * gcc.target/powerpc/dmr1024-compile.c: New test. * gcc.target/powerpc/dmr1024-invalid-use.c: New test. Diff: --- gcc/config/rs6000/rs6000-builtin.cc | 17 ++++++++ gcc/config/rs6000/rs6000.cc | 14 ++++++- gcc/config/rs6000/rs6000.h | 4 ++ .../gcc.target/powerpc/dmr1024-alignment.c | 33 +++++++++++++++ gcc/testsuite/gcc.target/powerpc/dmr1024-compile.c | 47 ++++++++++++++++++++++ .../gcc.target/powerpc/dmr1024-invalid-use.c | 38 +++++++++++++++++ 6 files changed, 152 insertions(+), 1 deletion(-) diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc index be768ddf3ec3..3fa61cde28a4 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 49695dfbc163..515507e6ee55 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -20739,6 +20739,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; @@ -28921,7 +28923,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) @@ -28930,6 +28933,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. */ @@ -29440,6 +29447,11 @@ rs6000_opaque_type_invalid_use_p (gimple *stmt) error ("type %<__vector_pair%> requires the %qs option", "-mmma"); return true; } + else if (mv == dmr1024_type_node) + { + 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 f002235e8e01..812f7e3398e2 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2277,6 +2277,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, @@ -2315,6 +2316,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, @@ -2376,6 +2378,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]) @@ -2414,6 +2417,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/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..11a54f5dd862 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/dmr1024-compile.c @@ -0,0 +1,47 @@ +/* { 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. There is no __dmr1024 move support + (movtdo) yet, so this deliberately never copies a __dmr1024 value; + only pointers to it are passed around. */ + +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.c b/gcc/testsuite/gcc.target/powerpc/dmr1024-invalid-use.c new file mode 100644 index 000000000000..860f26182735 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/dmr1024-invalid-use.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_future_compile_ok } */ +/* { dg-options "-mdejagnu-cpu=future -O2 -std=gnu17" } */ + +/* The __dmr1024 opaque type, like __vector_quad and __vector_pair + (see pr96506-1.c/pr96506-2.c), may not be used as a function + parameter or return value. Verify we flag errors on these uses + rather than ICE. */ + +extern void bar0 (); + +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; + bar0 (v); /* { dg-error "invalid use of Dense Math operand of type .__dmr1024. as a function parameter" } */ +} + +__dmr1024 +foo2 (__dmr1024 *src) +{ /* { dg-error "invalid use of Dense Math type .__dmr1024. as a function return value" } */ + return *src; +} + +dmr_t +foo3 (dmr_t *src) +{ /* { dg-error "invalid use of Dense Math type .__dmr1024. as a function return value" } */ + return *src; +}
