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.