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]>
