On Tue, 18 Aug 2026, Avinash Jayakar wrote:

> Hi,
> 
> I am trying to add a 256 byte opaque mode for the rs6000 backend in order to
> represent a 2048 bit (pair of 1024 bit DMR) registers, following a similar
> approach as we did for OO and XOmodes.
> 
> The problem is the mode_unit_size is declared as 'unsigned char' array in
> genmodes.cc. Because of this I get an overflow warning, and querying this 
> array
> for the new QDOmode implemented below will return 0.
> 
> mode_unit_size_inline (machine_mode mode)\n\
> {\n\
>   extern CONST_MODE_UNIT_SIZE unsigned char 
> mode_unit_size[NUM_MACHINE_MODES];\
> \n\
> 
> Is it safe to change this array type to unsigned int, since the struct 
> mode_data's
> fields for bytesize and ncomponents are also unsigned int?

I'd use unsigned short, it's important to not use an overly large data
structure for those common lookups to reduce cache footprint.  We
could possibly even dynamically size the component from genmodes?

As of "safe" it depends whether there are existing local variables
that would then truncate the read.  I don't see an easy way to reliably
detect those.

> Work in progress patch is below, here I am trying to add opaque mode in
> rs6000-modes.def.
> 
> Thanks and regards,
> Avinash
> 
> ---
>  gcc/config/rs6000/rs6000-builtin.cc | 16 ++++++++++++++++
>  gcc/config/rs6000/rs6000-modes.def  |  3 ++-
>  gcc/config/rs6000/rs6000.cc         | 15 +++++++++++----
>  gcc/config/rs6000/rs6000.h          |  4 ++++
>  4 files changed, 33 insertions(+), 5 deletions(-)
> 
> diff --git a/gcc/config/rs6000/rs6000-builtin.cc 
> b/gcc/config/rs6000/rs6000-builtin.cc
> index ad6f1fc09f4..0081c3cb0e4 100644
> --- a/gcc/config/rs6000/rs6000-builtin.cc
> +++ b/gcc/config/rs6000/rs6000-builtin.cc
> @@ -519,6 +519,8 @@ const char *rs6000_type_string (tree type_node)
>      return "__vector_quad";
>    else if (type_node == dmr1024_type_node)
>      return "__dmr1024";
> +  else if (type_node == dmr2048_type_node)
> +    return "__dmr2048";
>  
>    return "unknown";
>  }
> @@ -835,6 +837,17 @@ rs6000_init_builtins (void)
>    t = build_qualified_type (dmr1024_type_node, TYPE_QUAL_CONST);
>    ptr_dmr1024_type_node = build_pointer_type (t);
>  
> +  dmr2048_type_node = make_node (OPAQUE_TYPE);
> +  SET_TYPE_MODE (dmr2048_type_node, QDOmode);
> +  TYPE_SIZE (dmr2048_type_node) = bitsize_int (GET_MODE_BITSIZE (QDOmode));
> +  TYPE_PRECISION (dmr2048_type_node) = GET_MODE_BITSIZE (QDOmode);
> +  TYPE_SIZE_UNIT (dmr2048_type_node) = size_int (GET_MODE_SIZE (QDOmode));
> +  SET_TYPE_ALIGN (dmr2048_type_node, 512);
> +  TYPE_USER_ALIGN (dmr2048_type_node) = 0;
> +  lang_hooks.types.register_builtin_type (dmr2048_type_node, "__dmr2048");
> +  t = build_qualified_type (dmr2048_type_node, TYPE_QUAL_CONST);
> +  ptr_dmr2048_type_node = build_pointer_type (t);
> +
>    tdecl = add_builtin_type ("__bool char", bool_char_type_node);
>    TYPE_NAME (bool_char_type_node) = tdecl;
>  
> @@ -1337,6 +1350,9 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator 
> *gsi,
>      case OOmode:
>        lhs_type = vector_pair_type_node;
>        break;
> +    case QDOmode:
> +      lhs_type = dmr2048_type_node;
> +      break;
>      default:
>        gcc_unreachable ();
>      }
> diff --git a/gcc/config/rs6000/rs6000-modes.def 
> b/gcc/config/rs6000/rs6000-modes.def
> index 0ad326751c4..e9fdc145d43 100644
> --- a/gcc/config/rs6000/rs6000-modes.def
> +++ b/gcc/config/rs6000/rs6000-modes.def
> @@ -76,7 +76,8 @@ VECTOR_MODE (INT, SI, 2);     /*                 V2SI  */
>     combination.  */
>  PARTIAL_INT_MODE (TI, 128, PTI);
>  
> -/* Modes used by __vector_pair, __vector_quad and __dmr1024.  */
> +/* Modes used by __vector_pair, __vector_quad, __dmr1024, __dmr2048.  */
>  OPAQUE_MODE (OO, 32);
>  OPAQUE_MODE (XO, 64);
>  OPAQUE_MODE (TDO, 128);
> +OPAQUE_MODE (QDO, 256);
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index 99555988913..bca421fe1fb 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -1868,8 +1868,9 @@ rs6000_hard_regno_mode_ok_uncached (int regno, 
> machine_mode mode)
>    if (COMPLEX_MODE_P (mode))
>      mode = GET_MODE_INNER (mode);
>  
> -  /* No other types other than XOmode or TDOmode can go in DMRs.  */
> -  if (DMR_REGNO_P (regno) && !(mode ==XOmode || mode == TDOmode))
> +  /* No other types other than XOmode, TDOmode or QDOmode can go in DMRs.  */
> +  if (DMR_REGNO_P (regno)
> +      && !(mode == XOmode || mode == TDOmode || mode == QDOmode))
>      return 0;
>  
>    /* TDOmode value can be held in either 1 DMR register or 8 VSX
> @@ -1884,6 +1885,11 @@ rs6000_hard_regno_mode_ok_uncached (int regno, 
> machine_mode mode)
>        else
>       return 0;
>      }
> +  /* QDOmode needs even/odd DMR register pairs.  */
> +  if (mode == QDOmode)
> +    {
> +      return (TARGET_DMF && DMR_REGNO_P (regno) && (regno & 1) == 0);
> +    }
>  
>    /* Vector pair modes need even/odd VSX register pairs.  Only allow vector
>       registers.  */
> @@ -2011,8 +2017,9 @@ static bool
>  rs6000_modes_tieable_p (machine_mode mode1, machine_mode mode2)
>  {
>    if (mode1 == PTImode || mode1 == OOmode || mode1 == XOmode
> -      || mode1 == TDOmode || mode2 == PTImode || mode2 == OOmode
> -      || mode2 == XOmode || mode2 == TDOmode)
> +      || mode1 == TDOmode || mode1 == QDOmode || mode2 == PTImode
> +      || mode2 == OOmode || mode2 == XOmode || mode2 == TDOmode
> +      || mode2 == QDOmode)
>      return mode1 == mode2;
>  
>    if (ALTIVEC_OR_VSX_VECTOR_MODE (mode1))
> diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
> index bcd4c39d24d..c06de1396b1 100644
> --- a/gcc/config/rs6000/rs6000.h
> +++ b/gcc/config/rs6000/rs6000.h
> @@ -2277,6 +2277,7 @@ enum rs6000_builtin_type_index
>    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_dmr2048,            /* unsigned 2048-bit type (dmr2048).  */
>    RS6000_BTI_const_ptr_void,     /* const pointer to void */
>    RS6000_BTI_ptr_V16QI,
>    RS6000_BTI_ptr_V1TI,
> @@ -2316,6 +2317,7 @@ enum rs6000_builtin_type_index
>    RS6000_BTI_ptr_vector_pair,
>    RS6000_BTI_ptr_vector_quad,
>    RS6000_BTI_ptr_dmr1024,
> +  RS6000_BTI_ptr_dmr2048,
>    RS6000_BTI_ptr_long_long,
>    RS6000_BTI_ptr_long_long_unsigned,
>    RS6000_BTI_INTPTI,
> @@ -2378,6 +2380,7 @@ enum rs6000_builtin_type_index
>  #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 dmr2048_type_node                
> (rs6000_builtin_types[RS6000_BTI_dmr2048])
>  #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])
> @@ -2417,6 +2420,7 @@ enum rs6000_builtin_type_index
>  #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_dmr2048_type_node            
> (rs6000_builtin_types[RS6000_BTI_ptr_dmr2048])
>  #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])
>  
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Abhinav Puri; (HRB 36809, AG Nuernberg)

Reply via email to