https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106602
--- Comment #12 from Jeffrey A. Law <law at gcc dot gnu.org> ---
But insns 6, 7 and 8 aren't important here. We have a REG_EQUAL on insn 9
which indicates that (reg:DI 77) has the value 0xffffffffffffffc0. So I would
have expected combine to substitute that into the use of (reg:DI 77) in insn 10
which would give you a shot a recognizing the result is just a pair of shifts.
But the REG_EQUAL doesn't seem to be used in that case.
My insn #s are different, but here's the relevant part of the dump:
Trying 9 -> 15:
9: r139:DI=r141:DI-0x40
REG_DEAD r141:DI
REG_EQUAL 0x3fffffffc0
15: a0:DI=r138:DI&r139:DI
REG_DEAD r138:DI
REG_DEAD r139:DI
Failed to match this instruction:
(set (reg/i:DI 10 a0)
(and:DI (plus:DI (reg:DI 141)
(const_int -64 [0xffffffffffffffc0]))
(reg:DI 138)))
BUt we know the (and (plus ...))) is just 0x3fffffffc0, what's not clear is why
we don't use that information and try to recognize
(set (reg:DI 10) (and (reg:DI 138) (const_int 0x3fffffffc0))
Which is just a pair of shifts.