Hi,

On 27/08/26 10:59 PM, Avinash Jayakar wrote:
> The mode_unit_size array that is generated from
> emit_mode_unit_size_inline function currently hard codes the type of
> this array to unsigned char, since for most architectures the
> mode_unit_size never exceeded 255.
> 
> For rs6000 however, we add an opaque mode with 256 bytes which overflows
> this type. Therefore this patch adds a macro named MODE_UNIT_SIZE_TYPE
> in the generated file which is defined based on the maximum value that
> the mode_unit_size array will hold.
> if < 256, unsigned char
> else if < 1^16, unsigned short

s/1^16/2^16 
or 1<<16

> else, usigned int

s/usigned/unsigned

> 
> 2026-08-26  Avinash Jayakar  <[email protected]>
> 
> gcc/ChangeLog:
>       * genmodes.cc (emit_mode_unit_size): Generate MODE_UNIT_SIZE_TYPE macro 
> based

Line too long. Please format.

>       on values in mode_unit_size.
>       * machmode.h: Use the new macro.
> ---
>  gcc/genmodes.cc | 20 +++++++++++++++++---
>  gcc/machmode.h  |  2 +-
>  2 files changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
> index fa5f8923519..f50d39e4ea4 100644
> --- a/gcc/genmodes.cc
> +++ b/gcc/genmodes.cc
> @@ -1167,16 +1167,30 @@ emit_mode_unit_size_inline (void)
>    int c;
>    struct mode_data *m;
>  
> +  unsigned int max_type_size = 0;
> +  for_all_modes (c, m)
> +    {
> +      if (max_type_size < m->bytesize)

The 'if' condition here is not correct.
The guard compares against m->bytesize, but the value assigned may be the
component's (much smaller) size. Suppose the opaque 256-byte mode sets the
max to 256, and a later vector mode has bytesize 512 and a 4-byte component.
The guard passes and the max drops to 4. The generated type then becomes
unsigned char and the 256 overflows again. The result depends on mode ordering.
The fix is to compute the unit size first, then take the max:

unsigned int sz = (c != MODE_PARTIAL_INT && m->component)
                  ? m->component->bytesize : m->bytesize;
if (sz > max_type_size) max_type_size = sz;

> +     max_type_size = (c != MODE_PARTIAL_INT && m->component)
> +                     ? m->component->bytesize : m->bytesize;
> +    }
> +  if (max_type_size < (1 << 8))
> +    puts ("#define MODE_UNIT_SIZE_TYPE unsigned char\n");
> +  else if (max_type_size < (1 << 16))
> +    puts ("#define MODE_UNIT_SIZE_TYPE unsigned short\n");
> +  else
> +    puts ("#define MODE_UNIT_SIZE_TYPE unsigned int\n");
> +
>    puts ("\
>  #ifdef __cplusplus\n\
>  inline __attribute__((__always_inline__))\n\
>  #else\n\
>  extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\
>  #endif\n\
> -unsigned char\n\
> +MODE_UNIT_SIZE_TYPE\n\
>  mode_unit_size_inline (machine_mode mode)\n\
>  {\n\
> -  extern CONST_MODE_UNIT_SIZE unsigned char 
> mode_unit_size[NUM_MACHINE_MODES];\
> +  extern CONST_MODE_UNIT_SIZE MODE_UNIT_SIZE_TYPE 
> mode_unit_size[NUM_MACHINE_MODES];\
>  \n\
>    gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\
>    switch (mode)\n\
> @@ -1683,7 +1697,7 @@ emit_mode_unit_size (void)
>    int c;
>    struct mode_data *m;
>  
> -  print_maybe_const_decl ("%sunsigned char", "mode_unit_size",
> +  print_maybe_const_decl ("%sMODE_UNIT_SIZE_TYPE", "mode_unit_size",
>                         "NUM_MACHINE_MODES", adj_bytesize);
>  
>    for_all_modes (c, m)
> diff --git a/gcc/machmode.h b/gcc/machmode.h
> index b92b1572d8d..468fa886910 100644
> --- a/gcc/machmode.h
> +++ b/gcc/machmode.h

The function mode_to_unit_size() in machmode.h specifies the return type as 
'unsigned char'.
This needs to change.
Also, all the places in the code where mode_unit_size[] is used should be 
checked
to see if the correct type is used.

-Surya
> @@ -26,7 +26,7 @@ extern CONST_MODE_SIZE poly_uint16 
> mode_size[NUM_MACHINE_MODES];
>  extern CONST_MODE_PRECISION poly_uint16 mode_precision[NUM_MACHINE_MODES];
>  extern const unsigned short mode_inner[NUM_MACHINE_MODES];
>  extern CONST_MODE_NUNITS poly_uint16 mode_nunits[NUM_MACHINE_MODES];
> -extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];
> +extern CONST_MODE_UNIT_SIZE MODE_UNIT_SIZE_TYPE 
> mode_unit_size[NUM_MACHINE_MODES];
>  extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];
>  extern const unsigned short mode_next[NUM_MACHINE_MODES];
>  extern const unsigned short mode_wider[NUM_MACHINE_MODES];

Reply via email to