[Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685

amacleod at redhat dot com gcc-bugzilla@gcc.gnu.org
Mon Oct 26 15:58:03 GMT 2020


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

--- Comment #2 from Andrew Macleod <amacleod at redhat dot com> ---
  <bb 3> :
  f.0_1 = f;
  _2 = 1 % f.0_1;
  h_24 = (char) _2;
  _3 = _2;
  c = _3;
  _4 = b.a;
  _5 = (int) _4;
  _6 = ~_5;
  f = _6;
  if (_4 != -1)
    goto <bb 4>; [INV]
  else
    goto <bb 5>; [INV]

when calculating the outgoing_range_p() of edge 3->4,
we know that then range is  != -1. 

operator_not_equal::op1_range
calculates the range on the true side as:

     if (wi::eq_p (op2.lower_bound(), op2.upper_bound()))
        {
          r = op2;
          r.invert ();
        }
538               r = op2;
(gdb) p op2.dump(stderr)
<unnamed-signed:1> [-1, -1]$12 = void
(gdb) n
539               r.invert ();
(gdb) p r.dump(stderr)
<unnamed-signed:1> [-1, -1]$13 = void
(gdb) n
543           break;
(gdb) p r.dump(stderr)
UNDEFINED$14 = void

when we invert the range  <unnamed-signed:1> [-1, -1]
we should get  <unnamed-signed:1> [0, 0]
but instead its returning UNDEFINED.

which when the post dominated merge happens in bb5, we are unioning [-1,-1] and
undefined, producing [-1, -1] ofr the range of _4..
if we were unioning [-1, -1] and [0, 0] like we we are suppose to get, we'd get
VARYING, and the statement would not be incorrectly folded.


You can put a breakpoint in operator_not_equal::op1_range and it should be the
first time it is hit.


More information about the Gcc-bugs mailing list