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

            Bug ID: 128232
           Summary: loop-prefetch: reuse-volume overflow produces zero
                    reuse distances
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: xuexiaomei at hygon dot cn
  Target Milestone: ---

GCC 17.0.0 20261027 (experimental), x86_64-linux-gnu (LP64)
Unpatched trunk revision: 9c73440b6f8b81040379de62dc040aa8d2fd0803

The following compile-only tests report zero reuse distances in the
aprefetch dump on x86-64. This is caused by overflow in the reuse-distance
calculation: a 2^32-byte volume wraps to zero when stored in a 32-bit
unsigned variable. Other targets using this pass may encounter the same
overflow for particular test sizes.

Test case 1:

#define N 8192

double a[N][N];

double
sum_columns (void)
{
  unsigned i, j;
  double sum = 0;

  for (i = 0; i < N; i++)
    for (j = 0; j < N; j++)
      sum += a[j][i];

  return sum;
}

Command:

gcc -O2 -fno-tree-vectorize -fprefetch-loop-arrays \
  --param l1-cache-line-size=64 --param l2-cache-size=512 \
  -fdump-tree-aprefetch-details -S prefetch-volume-overflow-1.c

The aprefetch dump reports distance 0; the expected distance is 524288.
The initial modeled volume is 64 * 8192 * 8192 = 2^32 bytes.

Test case 2:

void
store (int *__restrict b, const int *__restrict c, int scalar)
{
  for (unsigned long j = 0; j < 536870912UL; ++j)
    b[j] = scalar * c[j];
}

Command:

gcc -O2 -fno-tree-vectorize -fno-tree-loop-distribute-patterns \
  -fprefetch-loop-arrays -fdump-tree-aprefetch-details \
  -S nontemporal-store-volume-overflow.c

The aprefetch dump reports two distances of 0. The volume is
8 * 536870912 = 2^32 bytes: a 4-byte read and a 4-byte write per iteration.

Reply via email to