https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87763
--- Comment #60 from Andrew Pinski <pinskia at gcc dot gnu.org> --- (In reply to Segher Boessenkool from comment #59) > You either do a define_split (splitting the above ior thing into the two > insns you want, during combine itself), or you do a define_insn_and_split, > allowing this whole thing as a single rtl insn (perhaps only before split1, > or whatever works best). That won't work for the above folding as you need to know the non-zero bits of r93 match up with the constant to the "and" (-256). Also this really should be a generic as I originally saw this issue on MIPS :). Here is a testcase which you will see the same issue as insv_1.c on powerpc64-linux-gnu (for little-endian just swap around the fields of the struct): typedef struct bitfield { unsigned short eight1: 8; unsigned short eight: 8; } bitfield; bitfield bfi1 (bitfield a, unsigned *b) { a.eight = *b; return a; } bitfield bfi1_1 (bitfield a, unsigned b) { a.eight = b; return a; } NOTICE how bfi1_1 uses one rlwimi while bfi1 has rlwinm followed by or but could just used rlwimi . This is a generic problem of combine wanting to use nonzerobits but that sometimes can remove "important" information.