https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127266
Bug ID: 127266
Summary: Missed vector optimization: `(((a ^ b) & C) == 0) | (a
!= b)` is not folded to all-true
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: ---
The following lane-wise vector expression is always true, but GCC does not fold
it to an all-true vector mask. The analogous scalar expression is folded to 1.
Testcase:
typedef unsigned long long v4u64 __attribute__((vector_size(32)));
typedef long long v4i64 __attribute__((vector_size(32)));
__attribute__((noipa)) v4i64
f (v4u64 a, v4u64 b)
{
v4u64 d = a ^ b;
v4u64 m = d & (v4u64) { 0xabcdULL, 0xabcdULL, 0xabcdULL, 0xabcdULL };
return (m == (v4u64) { 0, 0, 0, 0 }) | (a != b);
}
The testcase was derived from the scalar pattern in:
gcc/testsuite/gcc.dg/tree-ssa/pr102793-1.c
Compile with:
gcc -O2 -mavx2 -fno-tree-vectorize -S \
-fdump-tree-optimized testcase.c -o testcase.s
Expected result:
For each lane, let d = a ^ b. Since a != b is equivalent to d != 0, the
expression is equivalent to
((d & C) == 0) | (d != 0)
If d == 0, the first comparison is true. Otherwise, the second comparison is
true. Therefore every lane is always true, and the result can be folded to an
all-true vector mask:
return (v4i64) { -1LL, -1LL, -1LL, -1LL };
Current result:
The optimized GIMPLE still retains the full computation:
d_6 = a_4(D) ^ b_5(D);
m_7 = d_6 & { 43981, 43981, 43981, 43981 };
_1 = m_7 == { 0, 0, 0, 0 };
_2 = a_4(D) != b_5(D);
_3 = _1 | _2;
return VIEW_CONVERT_EXPR<v4i64>(_3);
For example, on x86-64 with AVX2, the generated code for f contains eight
vector instructions:
vpbroadcastq
vpxor
vpcmpeqq
vpand
vpxor
vpcmpeqq
vpcmpeqq
vpor
ret
An all-true vector can instead be produced with a single vector instruction:
vpcmpeqd %ymm0, %ymm0, %ymm0
ret
This appears to be a missed lane-wise boolean simplification. The equivalent
scalar form is already simplified by GCC.
Compiler:
Target: x86_64-pc-linux-gnu
Configure options: --enable-languages=c,c++ --disable-bootstrap
--disable-multilib --enable-checking=release
gcc version 17.0.0 20260827 (experimental) (GCC)
GCC source: g:d38b7b3