https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126537
Bug ID: 126537
Summary: [14/15/16/17 Regression] wrong code with PHI group
analyzer
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: ktkachov at gcc dot gnu.org
Target Milestone: ---
/* Wrong code from the ranger PHI group analyzer, gcc/gimple-range-phi.cc.
phi_group::is_modifier_p classifies the modifier statement with
gimple_range_ssa_p, which returns NULL for a name that occurs in an
abnormal PHI, so "k / x" looks like a one-operand modifier with the group
member in position 2. calculate_using_modifier then applies the modifier
with fold_range (nv, m_modifier, iter_value, q), and fur_list::get_operand
feeds the supplied range to the first operand that is an SSA_NAME, which is
k, not x. The group range is computed as 1 / VARYING = [-1, 1] instead of
VARYING / 1, and every value of x is folded into [-1, 1].
No undefined behaviour: the computed goto targets labels of this function,
sel & 1 is 0 or 1, x is 1 or k on entry to the division so there is no
division by zero and no INT_MIN / -1. */
__attribute__((noipa)) int
f (int n, int sel)
{
static const void *tab[] = { &&L0, &&L1 };
int k = 3;
if (sel & 2)
{
k = 4096;
goto *tab[sel & 1]; /* makes k an abnormal PHI at L0 */
}
L0:
{
int x = 1;
int i;
for (i = 0; i < n; i++)
x = k / x; /* x is operand 2 of the divide */
if (x > 1000)
return 1;
return 2;
}
L1:
return 5;
}
int
main (void)
{
/* sel = 2: k = 4096, jump to L0, one iteration, x = 4096 / 1 = 4096. */
if (f (1, 2) != 1)
__builtin_abort ();
/* sel = 0: fall through to L0 with k = 3, x = 3. */
if (f (1, 0) != 2)
__builtin_abort ();
return 0;
}
aborts at -O2 on aarch64 and passes at -O0