https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87104
--- Comment #9 from pipcet at gmail dot com --- (In reply to Richard Biener from comment #6) > So on GIMPLE the following are not canonicalized: > > <bb 2> [local count: 1073741825]: > _1 = i_4(D) & 7; > _8 = (int) i_4(D); > if (_1 == 6) > goto <bb 3>; [20.97%] > else > goto <bb 4>; [79.03%] > > vs. > > <bb 2> [local count: 1073741825]: > _1 = i_5(D) + 18446744073709551610; > _2 = _1 & 7; > _9 = (int) i_5(D); > if (_2 == 0) > goto <bb 3>; [34.00%] > else > goto <bb 4>; [66.00%] > > where I'd call the former better. Thus for some unknown constraint > on @1, @2 and @3 > > (simplify > (eq (convert? (bit_and (plus @0 INTEGER_CST@3) @2)) @1) > (eq (convert (bit_and @0 @2)) { ... })) I suggest that the constraint be that @2 is of the form 000...000111...111000...000 and @3 is of the form ???...??????...???000...000 and @1 is zero. So your plan is to canonicalize to (X & MASK) == VALUE first, then do something target-dependent to emit (X - VALUE) & MASK == 0 instead? How would the target realize that? I tried adding a peephole2 rule but that's apparently too late and doesn't match the insn sequences in Paul's test.