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);
}