https://gcc.gnu.org/g:beff5a27484189aade32f9a833f96f8310853ab0
commit beff5a27484189aade32f9a833f96f8310853ab0 Author: Manjunath S Matti <[email protected]> Date: Mon Jul 13 05:28:24 2026 -0500 rs6000: Add the __dmr1024 opaque type 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/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 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 806505220f29..4ecbbe43ba00 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 58103fd059b7..3379a3a0e1d4 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -20759,6 +20759,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; @@ -28944,7 +28946,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) @@ -28953,6 +28956,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. */ @@ -29434,33 +29441,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 420ab45af638..bcd4c39d24dc 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -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 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; +}
