https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127706
Bug ID: 127706
Summary: Missed vector optimization: (a - b) != 0 is not
simplified to a != b for unsigned vectors
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: mikaseianatsu at proton dot me
Target Milestone: ---
GCC keeps the subtraction in the following testcase, and it can be simplified
to a != b.
Testcase:
typedef unsigned int v8u32 __attribute__((vector_size(32)));
typedef int v8i32 __attribute__((vector_size(32)));
__attribute__((noipa)) v8i32
f (v8u32 a, v8u32 b)
{
v8u32 d = a - b;
return (v8i32) d != (v8i32) { 0, 0, 0, 0, 0, 0, 0, 0 };
}
Compile with:
gcc -O2 -mavx2 -fno-tree-vectorize -S \
-fdump-tree-optimized testcase.c -o testcase.s
Actual result:
The optimized GIMPLE retains the subtraction and the comparison against zero:
d_5 = a_3(D) - b_4(D);
_1 = VIEW_CONVERT_EXPR<vector(8) int>(d_5);
_2 = _1 != { 0, 0, 0, 0, 0, 0, 0, 0 };
return VIEW_CONVERT_EXPR<v8i32>(_2);
On x86-64 with AVX2, the instruction sequence for f is:
vpsubd
vpxor
vpcmpeqd
vpcmpeqd
ret
Expected result:
For unsigned subtraction, a - b is zero exactly when a == b. The cast does not
change whether the result is zero, so the function can be simplified to:
return a != b;
vpcmpeqd
vpxor
vpcmpeqd
ret
This avoids the vector subtraction and its dependency before the comparison.
Compiler:
gcc version 17.0.0 20260827 (experimental) (GCC)
Target: x86_64-pc-linux-gnu
GCC source: d38b7b34f4dc69f896e1fbd984b859365f3dd282