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

Reply via email to