LRA for avr: help with FP and elimination

Vladimir Makarov vmakarov@redhat.com
Fri Aug 11 16:02:13 GMT 2023


On 8/10/23 07:33, SenthilKumar.Selvaraj@microchip.com wrote:
>
> Hi Vlad,
>
>    I can confirm your commit (https://gcc.gnu.org/git?p=gcc.git;a=commit;h=2971ff7b1d564ac04b537d907c70e6093af70832)
>    fixes the above problem, thank you. However, I see execution failures if a
>    pseudo assigned to FP has to be spilled because of stack slot creation.
>
>    To reproduce, build the compiler just like above, and then do
>
> $ avr-gcc -mmcu=avr51 <gcc-src-dir>/gcc/testsuite/gcc.c-torture/execute/20050224-1.c -O2 -S -fdump-rtl-all
>
>    The execution failure occurs at this point
> 	
> 	movw r24,r2
> 	sbiw r24,36
> 	brne .L8
>
>     r2 is never set anywhere at all in the assembly.
>
> The relevant insns (in the IRA dump) are
>
> (insn 3 15 4 3 (set (reg/v:HI 51 [ j ])
>          (const_int 0 [0])) "gcc/gcc/testsuite/gcc.c-torture/execute/20050224-1.c":19:21 101 {*movhi_split}
>       (expr_list:REG_EQUAL (const_int 0 [0])
>          (nil)))
> ...
> (insn 28 27 67 8 (parallel [
>              (set (reg/v:HI 51 [ j ])
>                  (plus:HI (reg/v:HI 51 [ j ])
>                      (const_int 1 [0x1])))
>              (clobber (scratch:QI))
>          ]) "/home/i41766/code/personal/gcc/gcc/testsuite/gcc.c-torture/execute/20050224-1.c":28:8 175 {addhi3_clobber}
>       (nil))
> ...
> (jump_insn 44 43 45 13 (parallel [
>              (set (pc)
>                  (if_then_else (ne (reg/v:HI 51 [ j ])
>                          (const_int 36 [0x24]))
>                      (label_ref:HI 103)
>                      (pc)))
>              (clobber (scratch:QI))
>          ]) "/home/i41766/code/personal/gcc/gcc/testsuite/gcc.c-torture/execute/20050224-1.c":11:16 discrim 1 713 {cbranchhi4_insn}
>       (expr_list:REG_DEAD (reg/v:HI 51 [ j ])
>          (int_list:REG_BR_PROB 7 (nil)))
>   -> 103)
>
>    LRA deletes insns 3 and 28, and uses r2 in the jump_insn.
>
>    In the reload dump, for pseudo r51, I'm seeing this
> subreg regs:
> 	   Frame pointer can not be eliminated anymore
> 	   Spilling non-eliminable hard regs: 28 29
> 	 Spilling r51(28)
>    Slot 0 regnos (width = 0):	 46
>    Slot 1 regnos (width = 0):	 45
>
>    lra_update_fp2sp_elimination calls spill_pseudos with
>    HARD_FRAME_POINTER_REGNUM, and that sets reg_renumber[51] to -1.
>
>    Later down the line, process_bb_lives is called with dead_insn_p=true from
>    lra_create_lives_ranges_1 on the relevant BB (#8), and df_get_live_out
>    on that BB does not contain 51 (even though previous calls to the same BB did).
>    
> Breakpoint 8, process_bb_lives (bb=0x7fffea570240, curr_point=@0x7fffffffd838: 25, dead_insn_p=true) at gcc/gcc/lra-lives.cc:664
> 664	  function_abi last_call_abi = default_function_abi;
> (gdb) n
> 666	  reg_live_out = df_get_live_out (bb);
> (gdb)
> 667	  sparseset_clear (pseudos_live);
> (gdb) p debug_bitmap(reg_live_out)
>
> first = 0x321c128 current = 0x321c128 indx = 0
> 	0x321c128 next = (nil) prev = (nil) indx = 0
> 		bits = { 28 32 34 43 44 47 48 49 50 }
>
>    process_bb_lives then considers the insn setting 51 (and
>    the reload insns LRA created) as dead, and removes them.
>
> BB 8
>     Insn 67: point = 31, n_alt = -1
>     Insn 114: point = 31, n_alt = 3
>     Deleting dead insn 114
> deleting insn with uid = 114.
>     Insn 28: point = 31, n_alt = 1
>     Deleting dead insn 28
> deleting insn with uid = 28.
>     Insn 113: point = 31, n_alt = 2
>     Deleting dead insn 113
>
> Same for insn 3 as well
>
> BB 3
>     Insn 92: point = 40, n_alt = -1
>     Insn 5: point = 40, n_alt = 1
>     Insn 4: point = 41, n_alt = 3
>     Insn 3: point = 42, n_alt = 3
>     Deleting dead insn 3
> deleting insn with uid = 3.
>
>    Yet when it prints "Global pseudo live data has been updated" after
>    all this, r51 is live again :(
>
> BB 8:
>      livein: 8:
>
>         43   44   47   48   49   50   51
>      liveout: 8:
>
>         28   32   34   43   44   47   48   49   50   51
>
>    Eventually, it assigns 2 to r51, resulting in just the compare and
>    branch instruction remaining in the assembly.
>
>    Is this an LRA bug or is the target doing something wrong?
>
I've reproduced this.  Probably it is a bug with live info update when 
fp->sp elimination became invalid.

I'll start to work on this problem on the next week and hope to have a 
fix soon after that.




More information about the Gcc mailing list