Hi Kito

Root cause has been identified.

Here's the frame layout fo the TC, please use courier font :)
        +-------------------------------+ 
        |                               | 
        |  GPR save area  112 B         | 
        |                               |
        +-------------------------------+ 
        |                               |<-- fs0 is beyond sp based 12-bit 
range 
        |  FPR save area  96 B          |
        |                               |
        +-------------------------------+ 
        |                               |
        |  local variables              |<-- stack_pointer_rtx after 
riscv_first_stack_step
        |                               |
        +-------------------------------+ 

During stack frame allocation:
1. cm.push reserves 160 bytes, 112 for ra and sregs with 128-bit alignment as 
per ABI, and additional 48 bytes for first 6 fprs.
2. riscv_first_stack_step reserves 2032 bytes for the rest 6 fprs and local 
variables.
3. riscv_for_each_saved_reg tries to save fs0 which is beyond sp based 12-bit 
range,
    thus breaking gcc_assert (can_create_pseudo_p ()) in gen_reg_rtx when doing 
force reg as it's already after reload complete.

I tried with a solution like saving first 6 fprs immediately after cm.push. It 
seems working:)
I will fix epilogue correspondingly as well.

Thanks again for your test. 

BR, 
Fei

On 2023-08-16 16:33  Kito Cheng <kito.ch...@gmail.com> wrote:
>
>Hi Fei:
>
>Tried to use Jiawei's patch to test this patch and found some issue:
>
>
>> @@ -5430,13 +5632,15 @@ riscv_expand_prologue (void)
>>    /* Save the registers.  */
>>    if ((frame->mask | frame->fmask) != 0)
>>      {
>> -      HOST_WIDE_INT step1 = riscv_first_stack_step (frame, remaining_size);
>> -
>> -      insn = gen_add3_insn (stack_pointer_rtx,
>> -                           stack_pointer_rtx,
>> -                           GEN_INT (-step1));
>> -      RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
>> -      remaining_size -= step1;
>> +      if (known_gt (remaining_size, frame->frame_pointer_offset))
>> +        {
>> +          HOST_WIDE_INT step1 = riscv_first_stack_step (frame, 
>> remaining_size);
>> +          remaining_size -= step1;
>> +          insn = gen_add3_insn (stack_pointer_rtx,
>> +                                stack_pointer_rtx,
>> +                                GEN_INT (-step1));
>> +          RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
>> +        }
>>        riscv_for_each_saved_reg (remaining_size, riscv_save_reg, false, 
>>false);
>>      }
>>
>
>I hit some issue here during building libgcc, I use
>riscv-gnu-toolchain with --with-arch=rv64gzca_zcmp
>
>And the error message is:
>
>In file included from
>../../../../../riscv-gnu-toolchain-trunk/gcc/libgcc/unwind-dw2.c:1471:
>../../../../../riscv-gnu-toolchain-trunk/gcc/libgcc/unwind.inc: In
>function '_Unwind_Backtrace':
>../../../../../riscv-gnu-toolchain-trunk/gcc/libgcc/unwind.inc:330:1:
>internal compiler error: in gen_reg_rtx, at emit-rtl.cc:1176
> 330 | }
>     | ^
>0x83753a gen_reg_rtx(machine_mode)
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/emit-rtl.cc:1176
>0xf5566f maybe_legitimize_operand
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/optabs.cc:8047
>0xf5566f maybe_legitimize_operands(insn_code, unsigned int, unsigned
>int, expand_operand*)
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/optabs.cc:8191
>0xf511d9 maybe_gen_insn(insn_code, unsigned int, expand_operand*)
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/optabs.cc:8210
>0xf58539 expand_binop_directly
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/optabs.cc:1452
>0xf56666 expand_binop(machine_mode, optab_tag, rtx_def*, rtx_def*,
>rtx_def*, int, optab_methods)
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/optabs.cc:1539
>0xcbfdd0 force_operand(rtx_def*, rtx_def*)
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/expr.cc:8231
>0xc8fca1 force_reg(machine_mode, rtx_def*)
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/explow.cc:687
>0x144b8cd riscv_force_temporary
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/config/riscv/riscv.cc:1531
>0x144b8cd riscv_force_address
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/config/riscv/riscv.cc:1528
>0x144b8cd riscv_legitimize_move(machine_mode, rtx_def*, rtx_def*)
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/config/riscv/riscv.cc:2387
>0x1af063e gen_movdf(rtx_def*, rtx_def*)
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/config/riscv/riscv.md:2107
>0xcba503 rtx_insn* insn_gen_fn::operator()<rtx_def*,
>rtx_def*>(rtx_def*, rtx_def*) const
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/recog.h:411
>0xcba503 emit_move_insn_1(rtx_def*, rtx_def*)
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/expr.cc:4164
>0x143d6c4 riscv_emit_move(rtx_def*, rtx_def*)
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/config/riscv/riscv.cc:1486
>0x143d6c4 riscv_save_reg
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/config/riscv/riscv.cc:5715
>0x143e2b9 riscv_for_each_saved_reg
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/config/riscv/riscv.cc:5904
>0x14480d0 riscv_expand_prologue()
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/config/riscv/riscv.cc:6156
>0x1af57fb gen_prologue()
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/config/riscv/riscv.md:2816
>0x143c746 target_gen_prologue
>       ../../../../riscv-gnu-toolchain-trunk/gcc/gcc/config/riscv/riscv.md:3302
>
>
>Reduced case:
>
>$ riscv64-unknown-elf-gcc -march=rv64imafd_zicsr_zifencei_zca_zcmp
>-mabi=lp64d  unwind-dw2.i -Os
>
>typedef struct {
> struct {
>   struct {
>     struct {
>       long a
>     }
>   } a[129]
> }
>} b;
>struct c {
> void *a[129]
>} d() {
> struct c a;
> __builtin_unwind_init();
> b e;
> f(a, &e);
>}

Reply via email to