https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87104
pipcet at gmail dot com changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #44605|0 |1 is obsolete| | Attachment #44606|0 |1 is obsolete| | --- Comment #11 from pipcet at gmail dot com --- Created attachment 44617 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44617&action=edit WIP patch I'm having partial success with this patch, which does two things: 1. Canonicalize to the easier-to-read (X & A) == B form 2. Emit optimized lea-test sequence for (X & A) == B (1) is straightforward; we need a new routine to test that an integer masks a contiguous range of bit positions. (2) is straightforward except for there being three cases: 32-bit, 64-bit, and mixed. Emacs uses the mixed case, where the lower 3 bits of a 64 bit value are tested. The strange thing is that code like int h17(long int i) { if ((i & 12) == 12) return 1; return 0; } does not work. I see this intermediate RTL: (insn 7 6 8 2 (set (reg:CCZ 17 flags) (compare:CCZ (and:DI (not:DI (reg/v:DI 86 [ i ])) (const_int 12 [0xc])) (const_int 0 [0]))) "h17.c":4 15 {*cmpdi_1} (expr_list:REG_DEAD (reg:DI 88) Surely we should be dealing with a canonical form instead? Who's generating this non-canonical expression, and why? Is it legal to do something like { operands[2] = negate_rtx (operands[2]); } in a define_split? That would avoid the need to generate complicated RTL exprs from C. Anyway, this all needs more work and much more testing, but it's a start.