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

Reply via email to