Values of WIDE_INT_MAX_ELTS in gcc11 and gcc12 are different

Jakub Jelinek jakub@redhat.com
Tue Nov 9 09:10:23 GMT 2021


On Tue, Nov 09, 2021 at 08:13:57AM +0100, Richard Biener wrote:
> > Hi, I tried both the following patches:
> >
> > Patch1:
> >
> > [opc@qinzhao-ol8u3-x86 gcc]$ git diff
> > diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
> > index 0cba95411a6..ca49d2b4514 100644
> > --- a/gcc/internal-fn.c
> > +++ b/gcc/internal-fn.c
> > @@ -3073,12 +3073,14 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt)
> >        /* If this variable is in a register use expand_assignment.
> >          For boolean scalars force zero-init.  */
> >        tree init;
> > +      scalar_int_mode var_mode;
> >        if (TREE_CODE (TREE_TYPE (lhs)) != BOOLEAN_TYPE
> >           && tree_fits_uhwi_p (var_size)
> >           && (init_type == AUTO_INIT_PATTERN
> >               || !is_gimple_reg_type (var_type))
> >           && int_mode_for_size (tree_to_uhwi (var_size) * BITS_PER_UNIT,
> > -                               0).exists ())
> > +                               0).exists (&var_mode)
> > +         && targetm.scalar_mode_supported_p (var_mode))
> >         {
> >           unsigned HOST_WIDE_INT total_bytes = tree_to_uhwi (var_size);
> >           unsigned char *buf = (unsigned char *) xmalloc (total_bytes);
> >
> > AND
> >
> > Patch2:
> > diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
> > index 0cba95411a6..7f129655926 100644
> > --- a/gcc/internal-fn.c
> > +++ b/gcc/internal-fn.c
> > @@ -3073,12 +3073,14 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt)
> >        /* If this variable is in a register use expand_assignment.
> >          For boolean scalars force zero-init.  */
> >        tree init;
> > +      scalar_int_mode var_mode;
> >        if (TREE_CODE (TREE_TYPE (lhs)) != BOOLEAN_TYPE
> >           && tree_fits_uhwi_p (var_size)
> >           && (init_type == AUTO_INIT_PATTERN
> >               || !is_gimple_reg_type (var_type))
> >           && int_mode_for_size (tree_to_uhwi (var_size) * BITS_PER_UNIT,
> > -                               0).exists ())
> > +                               0).exists (&var_mode)
> > +         && have_insn_for (SET, var_mode))
> >         {
> >           unsigned HOST_WIDE_INT total_bytes = tree_to_uhwi (var_size);
> >           unsigned char *buf = (unsigned char *) xmalloc (total_bytes);
> >
> > Have the same effect:
> >
> > 1. Resolved the ICE in gcc11;
> > 2. For _Complex long double variables, both return FALSE, as a result, for PATTERN initialization of _Complex long double variables, now they are initialization with ZEROs instead of FEs.
> >
> > Let me know you opinion on this, If the above 2 is okay, then I might pick the above Patch 1 for the final patch to this issue.
> 
> I think zero-initialization is OK, but I'd choose Patch2 for
> consistency with what we do in the memcpy
> folding.

Note, I think the code leaks memory (buf is never freed) and
should be allocated using
  unsigned char *buf = XNEWVEC (unsigned char *, total_bytes);
and deallocated with XDELETEVEC (buf);
If lhs is SSA_NAME, I think it would be easiest to use
native_interpret_expr directly instead of finding some integral
mode, after memset just native_interpret_expr.
Should be guarded by
BITS_PER_UNIT == 8 && CHAR_BIT == 8 && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
but I think the current code assumes at least that BITS_PER_UNIT == CHAR_BIT
too anyway.
That way you get directly a constant init instead of hopping through
some integral mode which might not exist at all.
If lhs is not SSA_NAME but var_type has COMPLEX_TYPE or VECTOR_TYPE, there
is always an option to find var_mode only for the element type (i.e.
TREE_TYPE (var_type), use var_size for the element size too, and after
you compute init fold_build2 (COMPLEX_EXPR, ) or build_vector_from_val.
For VECTOR_TYPE one would need to check if the vector mode is supported,
sure (but if it isn't, it will go the BUILT_IN_MEMSET way, I'm pretty sure).

Also,
      tree value = (init_type == AUTO_INIT_PATTERN) ?
                    build_int_cst (integer_type_node,
                                   INIT_PATTERN_VALUE) :
                    integer_zero_node;
a few lines before has bad formatting, both ? and : should be at the start
of next lines rather than on end of the previous ones.

	Jakub



More information about the Gcc-patches mailing list