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.

Reply via email to