https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127916
--- Comment #1 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:e8621d3bdaf022078b98614a003ea2f5bf95e7b4 commit r17-5260-ge8621d3bdaf022078b98614a003ea2f5bf95e7b4 Author: Kyrylo Tkachov <[email protected]> Date: Thu Oct 15 20:08:43 2026 +0200 match-sat-alu.pd: Check operand types of signed SAT_ADD [PR127916] .SAT_ADD saturates in the type of its first operand. Two signed_integer_sat_add forms do not check that this is the result type. The .ADD_OVERFLOW (X, Y) form lost its types_match check in r15-6406: signed char another_sat (int a, int b) { signed char r; if (__builtin_add_overflow (a, b, &r)) return a < 0 ? SCHAR_MIN : SCHAR_MAX; return r; } __complex__ signed char _6; ... _6 = .ADD_OVERFLOW (a_4(D), b_5(D)); _2 = IMAGPART_EXPR <_6>; if (_2 != 0) ... _1 = REALPART_EXPR <_6>; ... _11 = _10 ^ 127; # _3 = PHI <_11(4), _1(3)> widening_mul replaces the PHI with _3 = .SAT_ADD (a_4(D), b_5(D)), which saturates in int, so another_sat (-1, 200) returns -57 instead of -128. The vectorizer goes wrong in the same way. Operands of the other sign and constants that do not fit the result type also go wrong. The IMM = -1 form matches X + -1 under a conversion to the result type, which can change the precision: short dec (int a) { unsigned ua = a, r = ua - 1; if ((a & (int) -ua) < 0) r = 0x8000u; return r; } At -Os this ICEs in wi::eq_p when checking is enabled. Without checking, dec (INT_MIN) returns 0 instead of -32768. Require X to have the result type in both forms. In the .ADD_OVERFLOW form, also require Y to have it or to be a constant that fits it. Both callers convert such a constant. Assert in the SAT_ADD callers that the first operand has the result type. Narrower Y operands no longer match. Trunk got those right only because expand converts each .SAT_ADD operand. Bootstrapped and tested as part of the series on aarch64-unknown-linux-gnu and x86_64-pc-linux-gnu. PR tree-optimization/127916 gcc/ChangeLog: * match-sat-alu.pd (signed_integer_sat_add): Check the operand types of the .ADD_OVERFLOW form and of the IMM = -1 form. * tree-ssa-math-opts.cc (match_saturation_add_with_assign): Assert that the first operand has the type of the result. (match_saturation_add): Likewise. * tree-vect-patterns.cc (vect_recog_sat_add_pattern): Likewise. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr127916.c: New test. Signed-off-by: Kyrylo Tkachov <[email protected]>
