https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128405
Bug ID: 128405
Summary: [17 Regression] Vectorized unsigned-char do-while
executes one iteration instead of 256
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: jeffchen006 at gmail dot com
Target Milestone: ---
GCC 17.0.0 20261102 (experimental), revision
7eb405c3d119d4fc84b31f21d6499069fbfedad8
Target: x86_64-linux-gnu; reproduced on Compiler Explorer.
Configure options (installation paths and packaging metadata omitted):
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
--disable-bootstrap --enable-multiarch --with-abi=m64
--with-multilib-list=m32,m64,mx32 --enable-multilib --enable-clocale=gnu
--enable-languages=c,c++,fortran,ada,objc,obj-c++,go,d,rust,m2,cobol,algol68
--enable-ld=yes --enable-gold=yes --enable-libstdcxx-time=yes
--enable-linker-build-id --enable-lto --enable-plugins --enable-threads=posix
The testcase is complete and has no #include dependencies. Compile and run with
no command-line arguments.
Testcase (bug-002.c):
int printf(const char *, ...);
int a[256];
int sum(unsigned char i, unsigned char end)
{
int s = 0;
do
s += a[i++];
while (i != end);
return s;
}
unsigned char x = 255, y = 255;
int main(void)
{
for (int j = 0; j < 256; j++)
a[j] = 1;
printf("%d\n", sum(x, y));
return 0;
}
Reproduction commands:
gcc -std=gnu2x -Wall -Wextra -O0 bug-002.c -o o0
./o0
gcc -std=gnu2x -Wall -Wextra -O3 bug-002.c -o o3
./o3
Expected: 256
Actual with -O0: 256
Actual with -O3: 1
Compilation produces no diagnostics with -Wall -Wextra.
The failure also persists with:
-O3 -fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations
Analysis and additional checks:
sum(255, 255) must run a complete cycle through all 256 unsigned-char values
before i equals end again. Every index is in bounds, each array element is 1,
and the accumulated sum is at most 256. -O3 instead prints 1.
Compiler Explorer GCC 16.2 prints 256 at -O3. Current trunk prints 256 at -O0,
but 1 at -O3. Adding -fno-tree-vectorize restores 256.
Suspected area: vectorizer no-wrap/versioning assumptions and the
representation of the 256-iteration count. Earlier bisection supplied with the
testcase points to df0ac78ff1d (vect: Request no-wrap bounds from DR analysis);
it was not re-bisected in this verification.
The ASan+UBSan+float-cast-overflow build runs without sanitizer diagnostics and
prints 256; instrumentation hides this optimization failure.