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

Jan Hubicka <hubicka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[14 regression] ICU         |[12/13/14 regression] ICU
                   |miscompiled since on x86    |miscompiled since on x86
                   |since                       |since
                   |r14-5109-ga291237b628f41    |r14-5109-ga291237b628f41

--- Comment #41 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
OK, the reason why this does not work is that ranger ignores earlier value
ranges on everything but default defs and phis.

// This is where the ranger picks up global info to seed initial
// requests.  It is a slightly restricted version of
// get_range_global() above.
//
// The reason for the difference is that we can always pick the
// default definition of an SSA with no adverse effects, but for other
// SSAs, if we pick things up to early, we may prematurely eliminate
// builtin_unreachables.
//
// Without this restriction, the test in g++.dg/tree-ssa/pr61034.C has
// all of its unreachable calls removed too early.
//
// See discussion here:
// https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571709.html

void
gimple_range_global (vrange &r, tree name, struct function *fun)
{
  tree type = TREE_TYPE (name);
  gcc_checking_assert (TREE_CODE (name) == SSA_NAME);

  if (SSA_NAME_IS_DEFAULT_DEF (name) || (fun && fun->after_inlining)
      || is_a<gphi *> (SSA_NAME_DEF_STMT (name)))
    { 
      get_range_global (r, name, fun);
      return;
    }
  r.set_varying (type);
}


This makes ipa-prop to ignore earlier known value range and mask the bug. 
However adding PHI makes the problem to reproduce:
#include <stdio.h>
#include <stdlib.h>
int data[100];
int c;

static __attribute__((noinline))
int bar (int d, unsigned int d2)
{
  if (d2 > 30)
          c++;
  return d + d2;
}
static int
test2 (unsigned int i)
{
  if (i > 100)
    __builtin_unreachable ();
  if (__builtin_expect (data[i] != 0, 1))
    return data[i];
  for (int j = 0; j < 100; j++)
    data[i] += bar (data[j], i&1 ? i+17 : i + 16);
  return data[i];
}

static int
test (unsigned int i)
{
  if (i > 10)
    __builtin_unreachable ();
  if (__builtin_expect (data[i] != 0, 1))
    return data[i];
  for (int j = 0; j < 100; j++)
    data[i] += bar (data[j], i&1 ? i+17 : i + 16);
  return data[i];
}
int
main ()
{
  int ret = test (1) + test (2) + test (3) + test2 (4) + test2 (30);
  if (!c)
          abort ();
  return ret;
}

This fails with trunk, gcc12 and gcc13 and also with Jakub's patch.

Reply via email to