Hi,
Addressed the comments in
https://gcc.gnu.org/pipermail/gcc-patches/2026-October/733494.html
Changes from v1:
- Correct commit message.
- Update the max value of the type size properly.
- Update type of mode_to_unit_size fn, which uses the updated array.
Bootstrapped and regtested on {x86_64,powerpc64le}-linux-gnu. Ok for
trunk?
Thanks,
Avinash
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 < 2^16, unsigned short
else, unsigned int
2026-10-12 Avinash Jayakar <[email protected]>
gcc/ChangeLog:
* genmodes.cc (emit_mode_unit_size): Generate MODE_UNIT_SIZE_TYPE
macro based on values in mode_unit_size.
* machmode.h: Use the new macro.
---
gcc/genmodes.cc | 21 ++++++++++++++++++---
gcc/machmode.h | 4 ++--
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
index fa5f8923519..ed8bfd3ba3a 100644
--- a/gcc/genmodes.cc
+++ b/gcc/genmodes.cc
@@ -1167,16 +1167,31 @@ emit_mode_unit_size_inline (void)
int c;
struct mode_data *m;
+ unsigned int max_type_size = 0;
+ for_all_modes (c, m)
+ {
+ unsigned int type_size = (c != MODE_PARTIAL_INT && m->component)
+ ? m->component->bytesize : m->bytesize;
+ if (max_type_size < type_size)
+ max_type_size = type_size;
+ }
+ 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 +1698,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 bc564d6bc13..fa439714bcb 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -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];
@@ -611,7 +611,7 @@ mode_to_inner (machine_mode mode)
/* Return the base GET_MODE_UNIT_SIZE value for MODE. */
-ALWAYS_INLINE unsigned char
+ALWAYS_INLINE MODE_UNIT_SIZE_TYPE
mode_to_unit_size (machine_mode mode)
{
#if GCC_VERSION >= 4001
--
2.54.0