https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97417

--- Comment #50 from Jim Wilson <wilson at gcc dot gnu.org> ---
The combine change is inconvenient.  We can't do that in stage3, and it means
we need to make sure that this doesn't break other targets.

If the combine change is a good idea, then I think you can just modify
is_just_move rather than add a new function.  Just skip over a ZERO_EXTEND or
SIGN_EXTEND before the the general_operand check.  We might need a mode check
against UNITS_PER_WORD since extending past the word size is not necessarily a
simple move.

So the problem stems from the code in combine that is willing to do a 2->2
split if neither original instruction is a simple move.  When we add a
SIGN_EXTEND or ZERO_EXTEND they aren't considered simple moves anymore.

There is still the question of why the instruction cost allows the change. 
First I noticed that riscv_address_cost has a hook to check for shorten_memrefs
but that riscv_rtx_costs isn't calling it.  It uses riscv_address_insns
instead.  So it seems like adding a shorten_memref check to the MEM case
riscv_rtx_costs might solve the problem.  But riscv_compressed_lw_address_p has
a !reload_completed check, and combine runs before reload, so that returns the
same result for both the new and old insns.  I think that reload_completed
check isn't quite right.  If we have a pseudo-reg, then we should allow that,
but if we have an offset that is clearly not compressible, then we should
reject it before reload.  So I think the reload_completed check should be moved
down to where it checks for a compressible register.  With those two changes, I
can make the testcase work without a combine change.  Though since I changed
how shorten_memrefs works we need a check to make sure this patch doens't
change code size.  I haven't tried to do that yet.

With my changes, in the combine dump, I see

Successfully matched this instruction:
(set (reg/f:DI 92)
    (plus:DI (reg:DI 96)
        (const_int 768 [0x300])))
Successfully matched this instruction:
(set (reg:DI 82 [ MEM[(intD.1 *)array_5(D) + 800B] ])
    (sign_extend:DI (mem:SI (plus:DI (reg:DI 96)
                (const_int 800 [0x320])) [1 MEM[(intD.1 *)array_5(D) + 800B]+0
S4 A32])))
rejecting combination of insns 27 and 6
original costs 4 + 16 = 20
replacement costs 4 + 20 = 24

so now the replacement gets rejected because of the increased address cost.

Reply via email to