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