https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112884
--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> --- (In reply to Richard Biener from comment #2) > I'd rather not do it in match.pd - well, maybe improve A / CST * CST > folding to consider nonzero bits, that is. I don't think there is anything to do in match.pd really. Since `(A / CST) * CST` already simplifies to `A & ~(CST1)` for power of 2. Rather VRP just needs to simplify `a_3(D) & 4294967294` to `a_3(D)` when it knows that `a_3(D) & 1` is 0 already (which it knows at that point: ``` a_3(D) [irange] unsigned int [0, 0][2, 4294967294] MASK 0xfffffffe VALUE 0x0 ``` ). Note we already handle: ``` unsigned src(unsigned a) { if (a % 2 != 0) __builtin_unreachable(); return (a / 2 * 2); } ``` Via match: ``` Folding statement: _3 = a_2(D) & 4294967294; Applying pattern match.pd:1572, gimple-match-6.cc:16797 gimple_simplified to _3 = a_2(D); Folded into: _3 = a_2(D); ``` This pattern uses get_nonzero_bits. get_nonzero_bits uses the global ranger to find out the nonzero bits. We could add a similar optimization directly to the folding part of VRP that uses the local ranger to find the nonzero bits.