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

--- Comment #4 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:6ac8df7a4992dc7c5eec1217808bea31c085ec74

commit r17-5259-g6ac8df7a4992dc7c5eec1217808bea31c085ec74
Author: Kyrylo Tkachov <[email protected]>
Date:   Thu Oct 15 19:36:08 2026 +0200

    match-sat-alu.pd: Check the .ADD_OVERFLOW type of SAT_U_ADD [PR127760]

    r17-4076 added unsigned_integer_sat_add forms that select a separate
    X + Y, but did not check the type of the .ADD_OVERFLOW result.  Its
    overflow flag describes that type, which can differ from the type of
    X + Y:

      unsigned
      u_sat (unsigned a, unsigned b)
      {
        unsigned char r;
        if (__builtin_add_overflow (a, b, &r))
          return -1u;
        return a + b;
      }

      __complex__ unsigned char _5;
      ...
      _5 = .ADD_OVERFLOW (a_3(D), b_4(D));
      _1 = IMAGPART_EXPR <_5>;
      if (_1 != 0)
      ...
      _6 = a_3(D) + b_4(D);
      # _2 = PHI <4294967295(2), _6(3)>

    widening_mul replaces the PHI with a 32-bit .SAT_ADD (a_3(D), b_4(D)), so
    u_sat (200, 100) returns 300 instead of UINT_MAX.  The vectorizer uses the
    same matcher, so loops of this form also became wrong vector .SAT_ADDs.

    Require the parts of the .ADD_OVERFLOW result to have the type of the
    addition.  The other unsigned .ADD_OVERFLOW forms select REALPART of the
    result, which already ties the two types.

    Bootstrapped and tested on aarch64-unknown-linux-gnu and
    x86_64-pc-linux-gnu.

            PR tree-optimization/127760

    gcc/ChangeLog:

            * match-sat-alu.pd (unsigned_integer_sat_add): Check the type of
the
            .ADD_OVERFLOW result in the forms that select a separate X + Y.

    gcc/testsuite/ChangeLog:

            * gcc.dg/torture/pr127760.c: New test.

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

Reply via email to