https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94216

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #1)
> I wonder if we shouldn't do:
> --- gcc/fold-const.c.jj       2020-03-18 12:47:36.000000000 +0100
> +++ gcc/fold-const.c  2020-03-18 17:34:14.586455801 +0100
> @@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.
>  #include "attribs.h"
>  #include "tree-vector-builder.h"
>  #include "vec-perm-indices.h"
> +#include "tree-ssa.h"
>  
>  /* Nonzero if we are folding constants inside an initializer; zero
>     otherwise.  */
> @@ -10262,6 +10263,10 @@ fold_binary_loc (location_t loc, enum tr
>    switch (code)
>      {
>      case MEM_REF:
> +      STRIP_USELESS_TYPE_CONVERSION (arg0);

We already applied STRIP_NOPS to arg0

> +      if (arg0 != op0)
> +     return fold_build2 (MEM_REF, type, arg0, op1);
> +
>        /* MEM[&MEM[p, CST1], CST2] -> MEM[p, CST1 + CST2].  */
>        if (TREE_CODE (arg0) == ADDR_EXPR
>         && TREE_CODE (TREE_OPERAND (arg0, 0)) == MEM_REF)
> to catch all similar issues.  Otherwise, we'd need to strip the useless type
> conversion at least in the case which triggers this:
>           return fold_build2 (MEM_REF, type,
>                               build_fold_addr_expr (base),
>                               int_const_binop (PLUS_EXPR, arg1,
>                                                size_int (coffset)));
> a few lines below this, where build_fold_addr_expr now returns a NOP_EXPR
> that we really want to strip again, even when op0 wasn't a NOP_EXPR.

True.  But note there could be a not useless type conversion here, for
example for MEM<void (*)()> [&a] and void *a for example.  Here I think
the better fix is (again) to use build1 and then in case the base was
a MEM_REF recurse to the preceeding pattern.

I'm testing such a patch.

Reply via email to