On 2024-07-07 22:53  Jeff Law <jeffreya...@gmail.com> wrote:
>
>
>
>On 6/8/24 2:36 PM, Jeff Law wrote:
>>
>>
>> On 6/5/24 8:42 PM, Fei Gao wrote:
>>
>>>> But let's back up and get a good explanation of what the problem is.
>>>> Based on patch 2/2 it looks like we have lost an assignment to the
>>>> return register.
>>>>
>>>> To someone not familiar with this code, it sounds to me like we've made
>>>> a mistake earlier and we're now defining a hook that lets us go back and
>>>> fix that earlier mistake.   I'm probably wrong, but so far that's what
>>>> it sounds like.
>>> Hi Jeff
>>>
>>> You're right. Let me rephrase  patch 2/2 with more details. Search /*
>>> feigao to location the point I'm
>>> tring to explain.
>>>
>>> code snippets from gcc/function.cc
>>> void
>>> thread_prologue_and_epilogue_insns (void)
>>> {
>>> ...
>>>    /*feigao:
>>>          targetm.gen_epilogue () is called here to generate epilogue
>>> sequence.
>>>     https://gcc.gnu.org/git/?
>>> p=gcc.git;a=commit;h=b27d323a368033f0b37e93c57a57a35fd9997864
>>>     Commit above tries in targetm.gen_epilogue () to detect if
>>>     there's li    a0,0 insn at the end of insn chain, if so, cm.popret
>>>     is replaced by cm.popretz and li    a0,0 insn is deleted.
>> So that seems like the critical issue.  Generation of the prologue/
>> epilogue really shouldn't be changing other instructions in the
>> instruction stream.  I'm not immediately aware of another target that
>> does that, an it seems like a rather risky thing to do.
>>
>>
>> It looks like the cm.popretz's RTL exposes the assignment to a0 and
>> there's a DCE pass that runs after insertion of the prologue/epilogue.
>> So I would suggest leaving the assignment to a0 in the RTL chain and see
>> if the later DCE pass after prologue generation eliminates the redundant
>> assignment.  That seems a lot cleaner.
>So I looked at this in a bit more detail.  I'm going to explicitly
>reject this patch now.
>
>The removal of the set to a0 in riscv_gen_multi_pop_insn looks wrong on
>multiple levels.  I don't think you have enough context in that routine
>or its callers to know if it's safe  ie given this fragment of RTL:
>
>> (call_insn 12 11 13 3 (parallel [
>>             (call (mem:SI (symbol_ref:SI ("test_1") [flags 0x41] 
>><function_decl 0x7ffff7796d00 test_1>) [0 test_1 S4 A32])
>>                 (const_int 0 [0]))
>>             (use (unspec:SI [
>>                         (const_int 0 [0])
>>                     ] UNSPEC_CALLEE_CC))
>>             (clobber (reg:SI 1 ra))
>>         ]) "j.c":14:9 441 {call_internal}
>>      (expr_list:REG_CALL_DECL (symbol_ref:SI ("test_1") [flags 0x41] 
>><function_decl 0x7ffff7796d00 test_1>)
>>         (nil))
>>     (expr_list:SI (use (reg:SI 10 a0))
>>         (nil)))
>>
>> (code_label 13 12 14 4 2 (nil) [1 uses])
>>
>> (note 14 13 19 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
>>
>> (insn 19 14 20 4 (set (reg/i:SI 10 a0)
>>         (const_int 0 [0])) "j.c":18:1 276 {*movsi_internal}
>>      (nil))
>>
>> (insn 20 19 24 4 (use (reg/i:SI 10 a0)) "j.c":18:1 -1
>>      (nil))
>
>
>You delete insns 19 and 20 resulting in this:
>
>> (call_insn 12 11 13 3 (parallel [
>>             (call (mem:SI (symbol_ref:SI ("test_1") [flags 0x41] 
>><function_decl 0x7ffff7796d00 test_1>) [0 test_1 S4 A32])
>>                 (const_int 0 [0]))
>>             (use (unspec:SI [
>>                         (const_int 0 [0])
>>                     ] UNSPEC_CALLEE_CC))
>>             (clobber (reg:SI 1 ra))
>>         ]) "j.c":14:9 441 {call_internal}
>>      (expr_list:REG_CALL_DECL (symbol_ref:SI ("test_1") [flags 0x41] 
>><function_decl 0x7ffff7796d00 test_1>)
>>         (nil))
>>     (expr_list:SI (use (reg:SI 10 a0))
>>         (nil)))
>>
>> (code_label 13 12 14 4 2 (nil) [1 uses])
>>
>> (note 14 13 24 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
>>
>> (note 24 14 0 NOTE_INSN_DELETED)
>
>Which is incorrect/inconsistent RTL.  And as I've noted before, it's
>conceptually wrong for the backend code to be removing insns from the
>insn chain during prologue/epilogue generation.
>
>I realize you're trying to use a hook to limit how this impacts other
>targets, but if you're making a bad decision in the RISC-V backend code,
>working around it with a target hook rather than fixing the core problem
>in the RISC-V backend just makes the whole situation worse.
>
>My suggest is this.  Leave the assignment to a0 and use alone.  That's
>likely going to result in some kind of code size regression, but not a
>correctness regression.  Then address the code size regressions with the
>invariant that prologue/epilogue generation must not change existing
>insns on the insn chain. 

Hi Jeff

Thanks for your patience.

Got your point never remove insns from the
insn chain during prologue/epilogue generation. 

As you suggested, I will fix this issue by leaving the assignment to a0 and use 
insn
with cm.popret. Then optimize to cm.popretz in correct pass in future if 
possilbe.

>jeff
>
>
>
>
>
>
>
>
>
>

Reply via email to