On 8/4/2026 3:58 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>

The rule folding (type) minmax ((wide_type) a, (wide_type) b) to
minmax (a, b) is restricted to scalars.  Extension is monotone, so it
commutes with the comparison and the outer truncation is exact, and the
argument is lanewise, so it holds for vectors unchanged.

The vector case additionally needs the narrow operation to be available,
otherwise vector lowering would scalarise what used to be a single wide
instruction.

   typedef int  v2si __attribute__((vector_size (8)));
   typedef long v2di __attribute__((vector_size (16)));
   v2si h (v2si a, v2si b)
   {
     v2di x = __builtin_convertvector (a, v2di);
     v2di y = __builtin_convertvector (b, v2di);
     return __builtin_convertvector (x < y ? x : y, v2si);
   }

aarch64 -O3 before:

        sshll   v0.2d, v0.2s, 0
        sshll   v1.2d, v1.2s, 0
        cmgt    v2.2d, v1.2d, v0.2d
        bsl     v2.16b, v0.16b, v1.16b
        xtn     v0.2s, v2.2d

after:

        smin    v0.2s, v0.2s, v1.2s

Require the wide vector MIN or MAX to have one use.  A shared wide
result would otherwise gain a second narrow operation.

Bootstrapped and tested on aarch64-none-linux-gnu.
Ok for trunk?
Thanks,
Kyrill

gcc/ChangeLog:

        * match.pd ((type) minmax ((wide_type) a, (wide_type) b)): Accept
        vector types, using element_precision and requiring the narrow
        operation to be supported.

gcc/testsuite/ChangeLog:

        * g++.dg/tree-ssa/vec-narrow-1.C: New test.
        * g++.dg/tree-ssa/vec-narrow-minmax-2.C: New test.
OK
jeff

Reply via email to