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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
Indeed:

-Setting value number of a.0_1 to &b (changed)
+Setting value number of a.0_1 to a.0_1 (changed)
+Using extra use virtual operand .MEM_39
+Making available beyond BB2 a.0_1 for value a.0_1
...
 Setting value number of _3 to &b (changed)
 Value numbering stmt = _4 = *_3;
-Setting value number of _4 to 0 (changed)
+Setting value number of _4 to _4 (changed)
+Making available beyond BB2 _4 for value _4
 Value numbering stmt = if (_4 != 0)
-marking known outgoing edge 2 -> 5 executable

and the IL difference is just

   <bb 2> [local count: 1073741824]:
   f = 0;
   a = &b;
-  c.2_18 = c;
-  *c.2_18 = &b;
+  j ={v} {CLOBBER};
+  c.2_40 = c;
+  *c.2_40 = &b;
   f = 1;
   a.0_1 = a;
   *a.0_1 = 0;

note that 'a' is ESCAPED and _18/_40 point to ESCAPED.  So what doesn't
work with the CLOBBER is

      /* If we reach a clobbering statement try to skip it and see if
         we find a VN result with exactly the same value as the
         possible clobber.  In this case we can ignore the clobber
         and return the found value.  */

in vn_reference_lookup_3 because that does a non-walking lookup.  I think
we have a duplicate report for this exact issue somewhere.

The clobber is removed at -O2 as part of the useless vars removal before
stdarg.  DCE2 leaves us with

   <bb 4> [local count: 8687547609]:
-  a = &b;
+  j[0] = &b;
+  _13 = j[0];
+  a = _13;
   j ={v} {CLOBBER};

so we have stray uses left with -O3 which is ultimatively because cunrolli
unrolls only the outer loop with -O3!?

Ah, the reason is try_unroll_loop_completely has

  /* See if we can improve our estimate by using recorded loop bounds.  */
  if ((allow_peel || maxiter == 0 || ul == UL_NO_GROWTH)
      && maxiter >= 0
      && (!n_unroll_found || (unsigned HOST_WIDE_INT)maxiter < n_unroll))
    {
      n_unroll = maxiter;
      n_unroll_found = true;
      /* Loop terminates before the IV variable test, so we cannot
         remove it in the last iteration.  */
      edge_to_cancel = NULL;
    }

but with -O3 we have !allow_peel and ul == UL_ALL (and maxiter == 1),
niter is unknown.  I changed this with
g:a52206ae28ed3e55d601118bedd52739456401ab but the intent there was
clearly to allow the peeling if we restrict the cases to UL_NO_GROWTH,
not to disallow it with UL_ALL.

Reply via email to