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

--- 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:003b6877618ad3e483d10d01198edfa2a58ee50e

commit r17-3787-g003b6877618ad3e483d10d01198edfa2a58ee50e
Author: Kyrylo Tkachov <[email protected]>
Date:   Wed Aug 19 12:29:46 2026 +0200

    Match: Only match signed saturating truncation at one precision [PR126982]

    signed_integer_sat_trunc builds the constants of

      (unsigned) X + NT_MAX + 1 > UNSIGNED_MAX ? saturate : (NT) X

    at the precision of X, but the captured constants belong to the type of
    the conversion, which the match never constrains.  A variable shift
    leaves the shift result in int and the comparison narrows it, so the two
    precisions differ and wi::eq_p asserts:

      during GIMPLE pass: vect
      internal compiler error: in decompose, at wide-int.h:1049
        gimple_signed_integer_sat_trunc
        vect_recog_sat_trunc_pattern

    Require the conversion to keep the precision of X.  A narrowing
    conversion compares only the low bits of X, so the expression is not a
    saturating truncation of X.  Nothing that used to be matched is lost,
    because any case whose precisions differed hit the assert rather than
    reaching a result.  Also require the result to be narrower than X, which
    is what makes the widths of the masks below valid.

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

    gcc/ChangeLog:

            PR tree-optimization/126982
            * match-sat-alu.pd (signed_integer_sat_trunc): Require the
            conversion to keep the precision of the operand, and the result
            to be narrower than it.

    gcc/testsuite/ChangeLog:

            PR tree-optimization/126982
            * gcc.dg/vect/pr126982.c: New test.

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

Reply via email to