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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
                 CC|                            |tnfchris at gcc dot gnu.org
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2026-10-12

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
-fno-trapping-math is required, v3 cannot mask the IEEE trapping compare and
with v4 we lack .COND_<tcc_comparison> (there's a PR about that).

So confirmed, but the comparison with clang is unfair - try -ftrapping-math
there.

> ./cc1 -quiet t.c -O3 -march=x86-64-v3 -fopt-info-vec -fno-trapping-math
t.c:13:14: optimized: loop vectorized using 32 byte vectors and unroll factor 4
t.c:13:14: optimized:  loop versioned for vectorization to enhance alignment
t.c:10:12: optimized: loop vectorized using 32 byte vectors and unroll factor 8
t.c:10:12: optimized:  loop versioned for vectorization to enhance alignment
t.c:24:28: optimized: loop vectorized using 32 byte vectors and unroll factor 8
t.c:32:28: optimized: loop vectorized using 32 byte vectors and unroll factor 4
t.c:32:28: optimized:  loop versioned for vectorization to enhance alignment

I'll note we seem to unroll the inner loop, vectorizing an early break one,
which explains that we need the masking (but only in the epilog?)?  Tamar?

There's also a missed optimization for the "bool" a_len_b reduction
(as it's unsigned) we're using

        vpand   %xmm0, %xmm2, %xmm0
        vshufps $136, %xmm1, %xmm0, %xmm0
        vpsrldq $8, %xmm0, %xmm1
        vpand   %xmm1, %xmm0, %xmm0
        vpsrldq $4, %xmm0, %xmm1
        vpand   %xmm1, %xmm0, %xmm0
        vmovd   %xmm0, %eax
        andl    $1, %eax

here instead of the vtest clang does.  The following can be used to avoid
unrolling the inner loop early.

unsigned
weakly_dominates(const double * restrict a, const double * restrict b, const
unsigned dim)
{
    enum { DIM_BLOCK=4 };
    int d = 0;
    for (; d+DIM_BLOCK <= dim; d += DIM_BLOCK) {
        unsigned a_leq_b = 1;
#pragma GCC unroll 0
        for (unsigned i = 0; i < DIM_BLOCK; i++)
            a_leq_b &= (a[d+i] <= b[d+i]);
        if (!a_leq_b)
            return 0;
    }
    for (; d < dim; d++)
        if (a[d] > b[d])
            return 0;
    return 1;
}

The PR should probably split, weakly_dominates_2 shows the AND reduction
issue for a single-bit set initial value.

Reply via email to