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

--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Kyrylo Tkachov <[email protected]>:

https://gcc.gnu.org/g:3c5cc8819fe03b63cba9ff82569623d092fdf0f5

commit r17-3786-g3c5cc8819fe03b63cba9ff82569623d092fdf0f5
Author: Kyrylo Tkachov <[email protected]>
Date:   Wed Aug 19 11:54:14 2026 +0200

    Match: Reject NARROW_CLIP saturating truncation at the minimum [PR126981]

    unsigned_integer_narrow_clip matches

      (UT) X > (NT) -1 ? (-X) >> (PREC (X) - 1) : X

    and rewrites it to SAT_U_TRUNC (MAX (0, X)).  The two agree everywhere
    except at the minimum of X's type, where the negation is its own
    inverse.  The shift then yields -1 and the expression gives NT_MAX,
    while MAX (0, X) gives 0.

    The negation is on the unsigned type in the gimple the pattern was
    written for, so there is no undefined behaviour to appeal to, and the
    rewrite changes the result of a well defined program.  Only accept the
    pattern when the minimum value is known not to occur.

      void
      clip (unsigned short *__restrict out, const int *__restrict in, int n)
      {
        for (int i = 0; i < n; ++i)
          {
            int x = in[i];
            out[i] = (unsigned) x > 65535u ? (int) (-(unsigned) x) >> 31 : x;
          }
      }

    For x == INT_MIN this stored 0 rather than 65535 on a target with a
    saturating truncation optab.

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

    gcc/ChangeLog:

            PR tree-optimization/126981
            * match-sat-alu.pd (unsigned_integer_narrow_clip): Require the
            operand to be known different from the minimum of its type.

    gcc/testsuite/ChangeLog:

            PR tree-optimization/126981
            * gcc.dg/vect/pr126981.c: New test.

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

Reply via email to