On Thu, Oct 3, 2024 at 6:09 PM Andrew Pinski <quic_apin...@quicinc.com> wrote:
>
> After fixing loop-im to do the correct overflow rewriting
> for pointer types too. We end up with code like:
> ```
>   _9 = (unsigned long) &g;
>   _84 = _9 + 18446744073709551615;
>   _11 = _42 + _84;
>   _44 = (signed char *) _11;
> ...
>   *_44 = 10;
>   g ={v} {CLOBBER(eos)};
> ...
>   n[0] = &f;
>   *_44 = 8;
>   g ={v} {CLOBBER(eos)};
> ```
> Which was not being recongized by the scope conflicts code.
> This was because it only handled one level walk backs rather than multiple 
> ones.
> This fixes it by using a work_list to avoid huge recursion and a visited 
> bitmape to avoid
> going into an infinite loops when dealing with loops.

Ick.  This is now possibly an unbound walk from every use (even duplicate use!).
Micro-optimizing would be restricting the INTEGRAL_TYPE_P types to ones
matching pointer size.  Another micro-optimization would be to track/cache
whether a SSA def is based on a pointer, more optimizing to cache what
pointer(s!) it is based on.

There's testcases in bugzilla somewhere hard on compile-time in this code
and I can imagine a trivial degenerate one to trigger the issue.

Richard.

> Bootstrapped and tested on x86_64-linux-gnu.
>
>         PR tree-optimization/111422
>
> gcc/ChangeLog:
>
>         * cfgexpand.cc (add_scope_conflicts_2): Rewrite to be a full walk
>         of all operands and their uses.
>
> Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
> ---
>  gcc/cfgexpand.cc | 46 +++++++++++++++++++++++++++-------------------
>  1 file changed, 27 insertions(+), 19 deletions(-)
>
> diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc
> index 6c1096363af..2e653d7207c 100644
> --- a/gcc/cfgexpand.cc
> +++ b/gcc/cfgexpand.cc
> @@ -573,32 +573,40 @@ visit_conflict (gimple *, tree op, tree, void *data)
>
>  /* Helper function for add_scope_conflicts_1.  For USE on
>     a stmt, if it is a SSA_NAME and in its SSA_NAME_DEF_STMT is known to be
> -   based on some ADDR_EXPR, invoke VISIT on that ADDR_EXPR.  */
> +   based on some ADDR_EXPR, invoke VISIT on that ADDR_EXPR. Also walk
> +   the assignments backwards as they might be based on an ADDR_EXPR.  */
>
> -static inline void
> +static void
>  add_scope_conflicts_2 (tree use, bitmap work,
>                        walk_stmt_load_store_addr_fn visit)
>  {
> -  if (TREE_CODE (use) == SSA_NAME
> -      && (POINTER_TYPE_P (TREE_TYPE (use))
> -         || INTEGRAL_TYPE_P (TREE_TYPE (use))))
> +  auto_vec<tree, 4> work_list;
> +  auto_bitmap visited_ssa_names;
> +  work_list.safe_push (use);
> +
> +  while (!work_list.is_empty())
>      {
> -      gimple *g = SSA_NAME_DEF_STMT (use);
> -      if (gassign *a = dyn_cast <gassign *> (g))
> +      use = work_list.pop();
> +      if (!use)
> +       continue;
> +      if (TREE_CODE (use) == ADDR_EXPR)
> +       visit (nullptr, TREE_OPERAND (use, 0), use, work);
> +      else if (TREE_CODE (use) == SSA_NAME
> +              && (POINTER_TYPE_P (TREE_TYPE (use))
> +                  || INTEGRAL_TYPE_P (TREE_TYPE (use))))
>         {
> -         if (tree op = gimple_assign_rhs1 (a))
> -           if (TREE_CODE (op) == ADDR_EXPR)
> -             visit (a, TREE_OPERAND (op, 0), op, work);
> +         gimple *g = SSA_NAME_DEF_STMT (use);
> +         if (!bitmap_set_bit (visited_ssa_names, SSA_NAME_VERSION(use)))
> +           continue;
> +         if (gassign *a = dyn_cast <gassign *> (g))
> +           {
> +             for (unsigned i = 1; i < gimple_num_ops (g); i++)
> +               work_list.safe_push (gimple_op (a, i));
> +           }
> +         else if (gphi *p = dyn_cast <gphi *> (g))
> +           for (unsigned i = 0; i < gimple_phi_num_args (p); ++i)
> +             work_list.safe_push (gimple_phi_arg_def (p, i));
>         }
> -      else if (gphi *p = dyn_cast <gphi *> (g))
> -       for (unsigned i = 0; i < gimple_phi_num_args (p); ++i)
> -         if (TREE_CODE (use = gimple_phi_arg_def (p, i)) == SSA_NAME)
> -           if (gassign *a = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (use)))
> -             {
> -               if (tree op = gimple_assign_rhs1 (a))
> -                 if (TREE_CODE (op) == ADDR_EXPR)
> -                   visit (a, TREE_OPERAND (op, 0), op, work);
> -             }
>      }
>  }
>
> --
> 2.34.1
>

Reply via email to