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

Signed saturating addition and subtraction can use a wider intermediate that
is clamped to the result type bounds:

   (T) MIN (MAX ((WT) X + (WT) Y, T_MIN), T_MAX)
     -> .SAT_ADD (X, Y)

Recognize addition and subtraction in both clamp nesting orders.  Require a
signed intermediate that is strictly wider than the result type.  This keeps
the arithmetic exact before the clamp.  Require the outer clamp to have one
use so that the replacement removes it.

Check signed saturation subtraction when the clamp is rooted at a conversion.

AArch64 -O2:

before:

        sxtw    x1, w1
        add     x0, x1, w0, sxtw
        mov     x1, -2147483648
        cmp     x0, x1
        csel    x0, x0, x1, ge
        mov     w1, 2147483647
        cmp     x0, x1
        csel    x0, x0, x1, le

after:

        fmov    s31, w0
        fmov    s30, w1
        sqadd   s31, s31, s30
        fmov    w0, s31

The other clamp forms have the same reduction.

Bootstrapped and tested on aarch64-none-linux-gnu.

Ok for trunk?

Changes since v3:
- Rebase on current trunk.

gcc/ChangeLog:

        * match-sat-alu.pd (signed_integer_sat_add): Add the two sided
        clamp on a wider intermediate, in both nesting orders.
        (signed_integer_sat_sub): Likewise.
        * tree-ssa-math-opts.cc (match_unsigned_saturation_sub): Rename
        to ...
        (match_saturation_sub_with_assign): ... this, and ask the signed
        predicate as well.
        (math_opts_dom_walker::after_dom_children): Update the callers,
        and call it for NOP_EXPR.

gcc/testsuite/ChangeLog:

        * gcc.target/aarch64/sat_s_clamp-1.c: New test.
        * gcc.target/aarch64/sat_s_clamp-2.c: New test.

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

Reply via email to