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.

Reply via email to