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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
     Ever confirmed|0                           |1

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
OK, so the issue is then LIM hoisting

  <bb 2> [local count: 118111600]:
  # PT = null 
  _2 = c;

which becomes available as CSE target in PRE and we then eventually elide
the

  c.2_6 = c;
  *c.2_6 = 1;

sequence because a store to 'null' is unnecessary.

That said, -fno-move-loop-stores makes it easier to look at what LIM does.

   <bb 2> [local count: 118111600]:
+  # PT = null 
+  _2 = c;
+  b.0_4 = b;
   goto <bb 5>; [100.00%]

   <bb 3> [local count: 955630224]:
   *d_12(D) = &c;
-  # PT = null 
-  _2 = c;
   _3 = *_2;
   a = _3;
-  b.0_4 = b;
   if (b.0_4 != 0)
     goto <bb 4>; [0.00%]
   else


The issue then still is that points-to analysis computed

  *d_13(D) = &c;
  # PT = null
  _1 = *d_13(D);
  # PT = null
  _2 = *_1;
  _3 = *_2;
  a = _3;
  b.0_4 = b;

and DOM (aka CSE) made that

  *d_12(D) = &c; 
  # PT = null
  _1 = &c;
  # PT = null
  _2 = c;
  _3 = *_2;
  a = _3;
  b.0_4 = b;

so basically the points-to info is UB manifested but with CSE the code
no longer has UB (but the points-to info is still there) and we hoist
the code, making the UB target to CSE.

Without DOM there's the dependence of the *d_13(D) load on the previous
store, so nothing is hoisted.

I don't see how to "fix" this.  A hack would be to try fixing up things
at the point we CSE the PT = null pointer with the later pointer with
sensible points-to info.  The most optimistic handling would intersect
both sets, but the latter is

  # PT = nonlocal unit-escaped null { D.2832 } (nonlocal, escaped)
  c.2_6 = c;

so we'd end up with 'null' this way.

We could start cleaning points-to info whenever we clear flow-sensitive
info.  For the reason that, as seen in this case, we inject flow-sensitive
info into the otherwise flow-insensitive solution by handling SSA default
defs specially:

      /* For undefined SSA names return nothing.  */
      else if (!ssa_defined_default_def_p (t))
        {
          cexpr.var = nothing_id;
          cexpr.type = SCALAR;
          cexpr.offset = 0;
          results->safe_push (cexpr);
          return;

short of using pt_anything here and polluting all PHI induced default defs
this way there's no solution.

Reply via email to