[Bug tree-optimization/126537] New: [14/15/16/17 Regression] wrong code with PHI group analyzer

"ktkachov at gcc dot gnu.org via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.