https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87763
--- Comment #24 from Richard Earnshaw <rearnsha at gcc dot gnu.org> --- (In reply to Steve Ellcey from comment #21) > Successfully matched this instruction: > (set (zero_extract:SI (reg/i:SI 0 x0) > (const_int 8 [0x8]) > (const_int 12 [0xc])) > (zero_extend:SI (reg:QI 1 x1 [ y ]))) > allowing combination of insns 8, 9 and 15 > original costs 4 + 4 + 4 = 12 > replacement cost 4 > deferring deletion of insn with uid = 9. zero_extract on a destination register is a read-modify write operation, which means that we'll almost never generate this through combine now as it would require the same pseudo register as both a source and a destination in the insns to be combined. In the past we'd sometimes see this in real code due to hard registers appearing to combine and giving it the opportunity to create the pattern. Perhaps its time for a new way of expressing bit-field insert operations in the compiler so that the entire operation is expressed on the right hand side of the set and the entire result can then be assigned to a pseudo (the or-and-and mess with constants is a nightmare to match, and a nightmare to emit the final instructions). Register allocation can then tie that to an input register if required. This would be a much better match for RISC based ISAs with bitfield insert operations, but probably wouldn't be much use on CISC architectures that can do bit-field inserts directly to memory. But clearly that's not a gcc-9 type change.