https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127381

            Bug ID: 127381
           Summary: Missed vector optimization: ((x >> 31) == 1) & 1 is
                    not folded to x >> 31
           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 function extracts the highest bit of each unsigned 32-bit vector
lane, compares it with one, and converts the comparison mask back to zero or
one. The result is exactly x >> 31, but GCC retains the comparison and mask
operation.



Compiler:

GCC 17.0.0 20260827 (experimental)
Target: x86_64-pc-linux-gnu
GCC source: d38b7b34f4dc69f896e1fbd984b859365f3dd282
Configure options: --enable-languages=c,c++ --disable-bootstrap
--disable-multilib --enable-checking=release



Testcase:

typedef unsigned int v8u32 __attribute__((vector_size(32)));

v8u32
f (v8u32 x)
{
        v8u32 bit = x >> 31;
        v8u32 one = { 1, 1, 1, 1, 1, 1, 1, 1 };
        return (v8u32) (bit == one) & one;
}

Compile with:

gcc -O2 -mavx2 -S -fdump-tree-optimized testcase.c -o testcase.s



Expected result:

For each unsigned 32-bit lane, bit = x >> 31 is either zero or one. Therefore
(bit == 1) & 1 produces exactly bit, so the function can be simplified to:

v8u32
f (v8u32 x)
{
        return x >> 31;
}



Current result:

The optimized GIMPLE retains the comparison and mask conversion:

bit_3 = x_2(D) >> 31;
_1 = bit_3 == { 1, 1, 1, 1, 1, 1, 1, 1 };
_6 = VIEW_CONVERT_EXPR(_1);
_4 = _6 & { 1, 1, 1, 1, 1, 1, 1, 1 };
return _4;

The generated code contains five vector instructions instead of one:

f:
vpcmpeqd %ymm1, %ymm1, %ymm1
vpsrld $31, %ymm0, %ymm0
vpsrld $31, %ymm1, %ymm1
vpcmpeqd %ymm1, %ymm0, %ymm0
vpand %ymm1, %ymm0, %ymm0
ret

This appears to be a missed vector simplification for a value known to be
either zero or one. The equivalent scalar expression is already simplified by
GCC.

Reply via email to