[Bug tree-optimization/97741] [11 Regression] ICE: verify_gimple failed with "-Os -fno-toplevel-reorder -fno-tree-ccp -fno-tree-fre" since r11-4724

amacleod at redhat dot com gcc-bugzilla@gcc.gnu.org
Fri Nov 6 16:00:12 GMT 2020


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

--- Comment #2 from Andrew Macleod <amacleod at redhat dot com> ---
Created attachment 49517
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49517&action=edit
don't lose info already in the global range

The problem here is the IL being changed by propagation under to covers
sometimes loses information.

The first thing examined is:
   e_4 = PHI <0(2), e_8(6)>
and the ranger goes off on the backedge to block 6 and eventually determines
that the edge 6->2 can never be executed, and thus e_8 is undefined on that
edge, which means the range of the PHI can be determined to be [0,0], and can
thus be folded.

Later on the propagator visits the blocks this originates in and sees
 e_8 = PHI <e_5(7)>

which is fed by the sequence:
<bb 7> :
  b.1_3 = b;
  if (b.1_3 != 0)
    goto <bb 6>; [INV]

<bb 8> :
  e_12 = e_5 + 1;

<bb 9> :
  # e_5 = PHI <0(5), e_12(8)>
  if (e_5 == 20)
    goto <bb 7>; [INV]


The ranger had figured out that although the branch says e_5 must be 20 on the
edge from bb5,it can only get to this code if it is 20 AND goes thru the e_12 =
e_5 + 1, which means e_12 must only be [21, 21]  which makes the whole thing
undefined.. and it is. it can never happen. 

However, when the propagator later visits stmts, and we get to 
e_12 = e_5 + 1;
when this is re-evaluated, e_5 is undefined and rather than propagating  e_12
as undefined, we decided a while ago to treat undefined as VARYING when doing
math.. we change e_12 to VARYING now, even tho we had earlier decided it was
[21,21]

This has ripple effects that eventually results in deciding that e_5 must be 
[20,20] coming from bb 7, it replaces that first PHI:
e_8 = PHI <e_5(7)>
with e_8 = PHI <20(7)>

when we then ask for the range of e_4 again at a use:
<bb 4> :
  _1 = (char) e_4;

e_4 = PHI <0(2), e_8(6)>
e_8 is now hardwired to [20,20] so it now recalculates e_4 to be
[0,0][20,20] instead of 0, and the engine does not fold the statement.

which ends up leaving e_4 in the IL with no definition.

THe easiest way to fix this sort of thing is to recognize that with the IL
changing under the covers in ways not really controlled by the ranger, we
should keep the previous value we defined, and refine it as we go along rather
than fully recalculating it.   

I think this will resolve an entire class of issues until we change the way we
propagate things, or revisit the slightly schizophrenic interpretation of
undefined.  The original RVRP pass simply propagated values via the
immediate-use chains, so the IL always reflected exactly what it knew. 

The attached patch is currently being tested.


More information about the Gcc-bugs mailing list