https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128404
Bug ID: 128404
Summary: [17 Regression] Vectorized unsigned average produces
arithmetic-shift result
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-010.c):
int printf(const char *, ...);
signed char a[8];
unsigned out[8];
void f(unsigned c)
{
for (int i = 0; i < 8; i++)
out[i] = ((unsigned long long)c + (unsigned)(c ? 0 : a[i])) / 2;
}
unsigned c0 = 0;
int main(void)
{
a[1] = -1;
f(c0);
printf("%x\n", out[1]);
return 0;
}
Reproduction commands:
gcc -std=gnu2x -Wall -Wextra -O0 bug-010.c -o o0
./o0
gcc -std=gnu2x -Wall -Wextra -O3 bug-010.c -o o3
./o3
Expected: 7fffffff
Actual with -O0: 7fffffff
Actual with -O3: ffffffff
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:
With c == 0 and a[1] == -1, converting a[1] to unsigned gives 0xffffffff.
Conversion to unsigned long long preserves that value, and unsigned 64-bit
division by 2 gives 0x7fffffff. The output element is unsigned, so printf("%x",
out[1]) must print 7fffffff. Current trunk at -O3 prints ffffffff.
Compiler Explorer GCC 16.2 prints 7fffffff at -O3. Current trunk also prints
7fffffff with -O3 -fno-tree-vectorize.
Suspected area: AVG_FLOOR fallback expansion using an arithmetic shift for an
unsigned average. Earlier bisection supplied with the reduction points to
9edd8aa65a3; that bisection was not repeated here.
The ASan+UBSan+float-cast-overflow build runs without sanitizer diagnostics and
prints the expected 7fffffff; instrumentation hides the failure.
Related: PR127216 is a RISC-V code-generation-quality regression in average
fallback handling; this testcase is an x86-64 wrong-result case. PR128142
concerns a signed wrapping vector add folded in match.pd and was fixed on trunk
on October 26; this testcase still fails on the November 2 snapshot. No
identical report was identified in the AVG_FLOOR searches.