https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100378
Richard Earnshaw <rearnsha at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |segher at kernel dot
crashing.org
--- Comment #10 from Richard Earnshaw <rearnsha at gcc dot gnu.org> ---
Still an issue. Prior to combine we have:
4: NOTE_INSN_BASIC_BLOCK 2
2: r103:DI=x0:DI
REG_DEAD x0:DI
3: NOTE_INSN_FUNCTION_BEG
6: r104:SI=sign_extend(r103:DI#0)
REG_DEAD r103:DI
11: x0:SI=r104:SI
REG_DEAD r104:SI
12: use x0:SI
At the start of combine we insert a new pseudo:
4: NOTE_INSN_BASIC_BLOCK 2
14: r105:DI=x0:DI
2: r103:DI=x105:DI
REG_DEAD x0:DI
3: NOTE_INSN_FUNCTION_BEG
6: r104:SI=sign_extend(r103:DI#0)
REG_DEAD r103:DI
11: x0:SI=r104:SI
REG_DEAD r104:SI
12: use x0:SI
and combine now tries:
Trying 2, 6 -> 11:
2: r103:DI=r105:DI
REG_DEAD r105:DI
6: r104:SI=sign_extend(r103:DI#0)
REG_DEAD r103:DI
11: x0:SI=r104:SI
REG_DEAD r104:SI
Failed to match this instruction:
(set (reg/i:SI 0 x0)
(ashiftrt:SI (subreg:SI (ashift:DI (reg:DI 105 [ s ])
(const_int 16 [0x10])) 0)
(const_int 16 [0x10])))
Successfully matched this instruction:
(set (reg:DI 104 [ _3 ])
(ashift:DI (reg:DI 105 [ s ])
(const_int 16 [0x10])))
Successfully matched this instruction:
(set (reg/i:SI 0 x0)
(ashiftrt:SI (subreg:SI (reg:DI 104 [ _3 ]) 0)
(const_int 16 [0x10])))
allowing combination of insns 2, 6 and 11
original costs 4 + 4 + 4 = 12
replacement costs 4 + 4 = 8
Because the costing (which is correct for each insn, but overall too much once
the register allocator has run) says the new sequence is cheaper.
This is fallout from the changes Segher made to combine; prior to that we
wouldn't have tried a 3 insn combine here.
But I think the main problem is that the substitution isn't being simplified
back to sign_extend, which would then match as a single insn.