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.