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

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
Hmm, I can't see what is wrong with the pattern.  We just replace

  _13 = (int) c_4;
  if (_13 <= 0)

with

  <bb 3>:
  _13 = (int) c_4;
  if (c_4 <= 0)

with c_4 being signed char.  Something else must go wrong here.  Still
-fno-tree-forwprop fixes the bug.

There is a missed optimization in VRP1 which ends up ifcombine doing sth.

VRP2 manages to mess things up then:

  <bb 2>:
  a.0_4 = a;
  c_5 = (char) a.0_4;
  _6 = (int) c_5;
  if (c_5 == 0)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  b = 0;
  goto <bb 5>;

  <bb 4>:
  _9 = ASSERT_EXPR <_6, _6 != 0>;
  b = 0;
  _10 = _9 | 128;
  if (_10 < 0)

a.0_4: VARYING
c_5: VARYING
_6: [0, 127]
_9: [1, 127]  EQUIVALENCES: { _6 } (1 elements)
_10: [128, 255]
.MEM_15: VARYING

as you can see _6 is already bogus.  Which is because of

  <bb 2>:
  a.0_4 = a;
  c_5 = (char) a.0_4;
  # RANGE [0, 127] NONZERO 127
  _6 = (int) c_5;

which is because of ifcombine hoisting the def of _6 in

  if (c_5 >= 0)
    goto <bb 3>;
  else
    goto <bb 5>;

  <bb 3>:
  # RANGE [0, 127] NONZERO 127
  _6 = (int) c_5;
  if (c_5 == 0)
    goto <bb 4>;
  else
    goto <bb 5>;

above the guarding check!

  <bb 2>:
  a.0_4 = a;
  c_5 = (char) a.0_4;
  # RANGE [0, 127] NONZERO 127
  _6 = (int) c_5;
  if (c_5 == 0)
    goto <bb 3>;
  else
    goto <bb 4>;

Reply via email to