https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86231
Bug ID: 86231
Summary: [8/9 Regression] vrp_meet causes wrong-code
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: jakub at gcc dot gnu.org
Target Milestone: ---
#define ONE ((void *) 1)
#define TWO ((void *) 2)
__attribute__((noipa)) int
foo (void *p, int x)
{
if (p == ONE) return 0;
if (!p)
p = x ? TWO : ONE;
return p == ONE ? 0 : 1;
}
int v[8];
int
main ()
{
if (foo ((void *) 0, 0) != 0
|| foo ((void *) 0, 1) != 1
|| foo (ONE, 0) != 0
|| foo (ONE, 1) != 0
|| foo (TWO, 0) != 1
|| foo (TWO, 1) != 1
|| foo (&v[7], 0) != 1
|| foo (&v[7], 1) != 1)
__builtin_abort ();
return 0;
}
is miscompiled starting with r251264, which just triggers a latent bug.
The bug is in:
Meeting
[1B, 2B]
and
~[0B, 1B] EQUIVALENCES: { p_4(D) p_8 } (2 elements)
to
~[0B, -1B]
Found new range for p_2: ~[0B, -1B]
which obviously isn't a correct range, the result of vrp_meet [1B, 2B] and
~[0B, 1B] should be ~[0B, 0B].
--- gcc/tree-vrp.c.jj 2018-05-31 20:53:31.200438223 +0200
+++ gcc/tree-vrp.c 2018-06-20 08:52:16.218963382 +0200
@@ -5922,9 +5922,9 @@ union_ranges (enum value_range_type *vr0
if (TREE_CODE (*vr0min) == INTEGER_CST)
{
*vr0type = vr1type;
- *vr0min = vr1min;
*vr0max = int_const_binop (MINUS_EXPR, *vr0min,
build_int_cst (TREE_TYPE (*vr0min),
1));
+ *vr0min = vr1min;
}
else
goto give_up;
fixes this.