https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56924
--- Comment #3 from Joshua Conner <josh.m.conner at gmail dot com> --- It appears that gcc has a different approach now, which has its own advantages and disadvantages. Specifically, when I compile this same example I'm now seeing an initial tree of: if ((SAVE_EXPR <BIT_FIELD_REF <input, 8, 0> & 240>) == 224 || (SAVE_EXPR <BIT_FIELD_REF <input, 8, 0> & 240>) == 240) { bar (); } Which indeed generates much better assembly code (for ARM): and r0, r0, #224 cmp r0, #224 beq .L4 But with a slight modification of the original code to: if ((input.val == 0xd) || (input.val == 0xe) || (input.val == 0xf)) bar(); The tree looks like: if (((SAVE_EXPR <BIT_FIELD_REF <input, 8, 0> & 240>) == 208 || (SAVE_EXPR <BIT_FIELD_REF <input, 8, 0> & 240>) == 224) || (BIT_FIELD_REF <input, 8, 0> & 240) == 240) And the generated assembly is: uxtb r0, r0 and r3, r0, #240 and r0, r0, #208 cmp r0, #208 cmpne r3, #224 beq .L4 Which could be much better as: ubfx r0, r0, #4, #4 cmp r0, #12 bhi .L4