On 9/16/26 9:16 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>

Signed saturating truncation currently requires the unsigned range type to
have the same precision as the signed input.  This rejects a wider range type
even though it preserves every input value.

Allow the range type to be at least as wide as the input.  Continue to require
a result narrower than the input.  Construct the offset and limit constants
at the range precision.  Use wide-int operations that do not depend on
host-width shifts.

Tests cover a valid 16-bit input with a 32-bit range and an 8-bit result.  They
also verify that a 17-bit range for a 32-bit input remains rejected because it
can discard input bits.

With AArch64 -O3 -march=armv8-a -mmax-vectorization and
--param=vect-epilogues-nomask=0:

before, 16 elements per iteration:

        ldp     q28, q27, [x3], 32
        uzp1    v26.16b, v28.16b, v27.16b
        saddl   v0.4s, v28.4h, v31.4h
        saddl2  v24.4s, v28.8h, v31.8h
        saddl   v23.4s, v27.4h, v31.4h
        saddl2  v25.4s, v27.8h, v31.8h
        ushr    v28.8h, v28.8h, 15
        ushr    v27.8h, v27.8h, 15
        cmhi    v0.4s, v0.4s, v30.4s
        cmhi    v24.4s, v24.4s, v30.4s
        cmhi    v23.4s, v23.4s, v30.4s
        cmhi    v25.4s, v25.4s, v30.4s
        uzp1    v27.16b, v28.16b, v27.16b
        uzp1    v24.8h, v0.8h, v24.8h
        uzp1    v25.8h, v23.8h, v25.8h
        neg     v27.16b, v27.16b
        uzp1    v25.16b, v24.16b, v25.16b
        eor     v27.16b, v27.16b, v29.16b
        bif     v27.16b, v26.16b, v25.16b
        str     q27, [x4], 16

after, 8 elements per iteration:

        ldr     q31, [x1, x4]
        sqxtn   v31.8b, v31.8h
        str     d31, [x0, x3]

Bootstrapped and tested on aarch64-none-linux-gnu.
Tested on x86_64-pc-linux-gnu.

Ok for trunk?

Changes since v3:
- Rebase on current trunk.

gcc/ChangeLog:

        * match-sat-alu.pd (signed_integer_sat_trunc): Allow a wider lossless
        unsigned range type.  Continue to require a narrowing result.  Construct
        the expected constants at the range precision.

gcc/testsuite/ChangeLog:

        * gcc.dg/vect/vect-sat-trunc-range-precision-1.c: New test.
        * gcc.target/aarch64/vect-sat-trunc-range-precision-1.c: Likewise.
        * gcc.target/aarch64/vect-sat-trunc-range-precision-negative-1.c:
        Likewise.

Signed-off-by: Kyrylo Tkachov <[email protected]>
OK
jeff

Reply via email to