https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120524
--- Comment #3 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jeff Law <[email protected]>: https://gcc.gnu.org/g:3383c738122861c52c150483b012be25d9b9dbac commit r17-5256-g3383c738122861c52c150483b012be25d9b9dbac Author: Avinal Kumar <[email protected]> Date: Fri Oct 16 07:36:25 2026 -0600 match.pd: Use wide_int for shift-and-mask folding [PR tree-optimization/120524] The pattern that folds (X >> C1) & C2 and (X << C1) & C2 was limited to types with precision <= HOST_BITS_PER_WIDE_INT because it used unsigned HOST_WIDE_INT for mask and zerobits arithmetic. This prevents the optimization from firing on __int128 and wider types at the GIMPLE level. Convert the pattern to use wide_int and remove the TYPE_PRECISION guard. Replace the mode-mask loop with wi::exact_log2 (newmask + 1) to check whether newmask is (2^n - 1) for a power-of-two n >= BITS_PER_UNIT. Handle the case where newmask is all-ones at full type precision separately, since newmask + 1 overflows to zero in that case. --- Changes from v2: - use operator instead of explicit function calls, wi:: supports operator overloading - split tests into right shift with negative assetion and left shift with positive assertion and regression guard I also found a case for option 2 as discussed in the last patch: __int128 f(__int128 a) { return (a << 8) & ((__int128)0xff00); } Without the patch (128-bit, pattern skipped): keeps & 65280 (0xff00) With the patch: widens to & 65535 (0xffff - 16-bit mode mask) this was not required if going for option one, so not included in the patch. PR tree-optimization/120524 gcc/ChangeLog: * match.pd: Use wide_int for shift-and-mask folding [PR120524] gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr120524-1.c: New test. * gcc.dg/tree-ssa/pr120524-2.c: New test. Signed-off-by: Avinal Kumar <[email protected]>
