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

            Bug ID: 68465
           Summary: pass_lim doesn't detect identical loop entry
                    conditions
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vries at gcc dot gnu.org
  Target Milestone: ---

Consider testcase test.c:
...
int a;
int *p = &a;

int
foo (int n)
{
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < n; ++j)
      *p += j + i;

  return a;
}
...

Compiled like this:
...
$ gcc -O2 -S -fdump-tree-all-details test.c -fno-tree-pre
-fno-tree-dominator-opts
...

Before pass_lim, we have:
...
foo (int n)
{
  int j;
  int i;
  int * p.0_7;
  int _9;
  int _10;
  int _11;
  int _15;

  <bb 2>:
  if (n_6(D) > 0)
    goto <bb 7>;
  else
    goto <bb 8>;

  <bb 7>:
  goto <bb 5>;

  <bb 11>:

  <bb 5>: outer loop header
  # i_21 = PHI <i_14(11), 0(7)>
  if (n_6(D) > 0)
    goto <bb 13>;
  else
    goto <bb 14>;

  <bb 14>:
  goto <bb 4>;

  <bb 13>:
  goto <bb 3>;

  <bb 9>: inner loop latch

  <bb 3>: inner loop header
  # j_22 = PHI <j_13(9), 0(13)>
  p.0_7 = p;
  _9 = *p.0_7;
  _10 = i_21 + j_22;
  _11 = _9 + _10;
  *p.0_7 = _11;
  j_13 = j_22 + 1;
  if (n_6(D) > j_13)
    goto <bb 9>;
  else
    goto <bb 10>;

  <bb 10>:

  <bb 4>: outer loop latch
  i_14 = i_21 + 1;
  if (n_6(D) > i_14)
    goto <bb 11>;
  else
    goto <bb 12>;

  <bb 12>:
  goto <bb 6>;

  <bb 8>:

  <bb 6>:
  _15 = a;
  return _15;

}
...

The store motion in pass_lim manages to hoist the store out of the inner loop,
but not the outer loop.

When doing store_motion_loop for the outer loop, can_sm_ref_p fails here:
...
  if ((tree_could_trap_p (ref->mem.ref)
       || (DECL_P (base) && TREE_READONLY (base)))
      && !ref_always_accessed_p (loop, ref, true))
    return false;
...
because tree_could_trap_p (ref->mem.ref) is true, and ref_always_accessed_p
(loop, ref, true) is false.

The fact that if you enter the first loop, you enter the second loop (because
they have identical loop entry conditions) is not taken into account.

Reply via email to