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

            Bug ID: 125815
           Summary: IVOPT determine_base_object is broken
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: internal-improvement
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rguenth at gcc dot gnu.org
  Target Milestone: ---

Possibly wrong-code, but w/o testcase.  IVOPTs dives into the GENERIC
expression for the base of an induction variable and gathers what looks like
"base objects"
from participating ADDR_EXPRs and SSA pointers, declaring "win" when it finds
exactly one, defeat if it finds none and a special "win" when it finds
multiple.
This is of course quite broken as it happily dives into integer computations in
the process and thus resembles all issues of RTL find_base_object (before that
was fixed to some extent).

Esp. the 'integer_zero_node' base is odd, as uses of iv->base_object never
explicitly check for that.

Of course all this is deep-wired into how IVOPTs processes bases and
esp. non IP_ORIGINAL IV candidates are always setup as 'unsigned'
rather than pointers.

All of this needs to be changed to preserve pointer-ness (and signedness?)
throughout analysis, esp. for determining the "BASE" we eventually put
in a TARGET_MEM_REF.

Changing determine_base_object to the following will not only produce
tons of TMR [0B, ... ] but also cause execution FAILs, which must surely
be latent issues [with TMRs with zero base?]

static tree
determine_base_object (struct ivopts_data *, tree expr)
{
  if (! POINTER_TYPE_P (TREE_TYPE (expr)))
    return NULL_TREE;

  do 
    {
      switch (TREE_CODE (expr))
        {
        case POINTER_PLUS_EXPR:
          expr = TREE_OPERAND (expr, 0);
          continue;
        case BIT_AND_EXPR:
          if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST)
            {
              expr = TREE_OPERAND (expr, 0);
              continue;
            }
          break; 
        case ADDR_EXPR: 
          {
            tree base = get_base_address (TREE_OPERAND (expr, 0));
            if (base && TREE_CODE (base) != MEM_REF)
              expr = fold_convert (ptr_type_node, build_fold_addr_expr (base));
            break;
          }
        default:
          break;
        }
      return expr;
    }
  while (1);
}

Reply via email to