[Bug rtl-optimization/116778] [lra][avr] Wrong code with -mlra (bitfld-lra.c)
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Sat Dec 7 09:47:57 GMT 2024
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116778
--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Denis Chertykov <denisc@gcc.gnu.org>:
https://gcc.gnu.org/g:279b3c71702de150eade19635bdbd26ba440b8eb
commit r15-6008-g279b3c71702de150eade19635bdbd26ba440b8eb
Author: Denis Chertykov <chertykov@gmail.com>
Date: Sat Dec 7 13:47:04 2024 +0400
The fix for PR116778:
Brief:
The bug appears in LRA after rematerialization pass while creating live
ranges.
File lra.cc:
*************************************************************
/* Now we know what pseudos should be spilled. Try to
rematerialize them first. */
if (lra_remat ())
{
/* We need full live info -- see the comment above. */
lra_create_live_ranges (lra_reg_spill_p, true);
*************************************************************
Wrong call `lra_create_live_ranges (lra_reg_spill_p, true)'
It have to be `lra_create_live_ranges (true, true)'.
The explanation:
**********************************
int main (void)
{
if (a.u33 * a.u33 != 0)
------^^^^^^^^^^^^^
goto abrt;
if (a.u33 * a.u40 * a.u33 != 0)
**********************************
The bug appears here.
Part of the expression `a.u33 * a.u33'
Before LRA:
*************************************************************
(insn 13 11 15 2 (set (reg:QI 184 [ _1+3 ])
(mem/c:QI (const:HI (plus:HI (symbol_ref:HI ("a") [flags 0x2]
<var_decl 0x7c866435d000 a>)
(const_int 3 [0x3]))) [1 a+3 S1 A8])) "bf.c":11:8 86
{movqi_insn_split}
(nil))
(insn 15 13 16 2 (set (reg:QI 64 [ a+4 ])
(mem/c:QI (const:HI (plus:HI (symbol_ref:HI ("a") [flags 0x2]
<var_decl 0x7c866435d000 a>)
(const_int 4 [0x4]))) [1 a+4 S1 A8])) "bf.c":11:8 86
{movqi_insn_split}
(nil))
(insn 16 15 20 2 (set (reg:QI 185 [ _1+4 ])
(zero_extract:QI (reg:QI 64 [ a+4 ])
(const_int 1 [0x1])
(const_int 0 [0]))) "bf.c":11:8 985 {*extzvqi_split}
(nil))
*************************************************************
After LRA:
*************************************************************
(insn 587 11 13 2 (set (reg:QI 24 r24 [368])
(mem/c:QI (const:HI (plus:HI (symbol_ref:HI ("a") [flags 0x2]
<var_decl 0x7c866435d000 a>)
(const_int 3 [0x3]))) [1 a+3 S1 A8])) "bf.c":11:8 86
{movqi_insn_split}
(nil))
(insn 13 587 15 2 (set (mem/c:QI (plus:HI (reg/f:HI 28 r28)
(const_int 1 [0x1])) [4 %sfp+1 S1 A8])
(reg:QI 24 r24 [368])) "bf.c":11:8 86 {movqi_insn_split}
(nil))
(insn 15 13 16 2 (set (reg:QI 6 r6 [orig:64 a+4 ] [64])
(mem/c:QI (const:HI (plus:HI (symbol_ref:HI ("a") [flags 0x2]
<var_decl 0x7c866435d000 a>)
(const_int 4 [0x4]))) [1 a+4 S1 A8])) "bf.c":11:8 86
{movqi_insn_split}
(nil))
(insn 16 15 572 2 (set (reg:QI 24 r24 [orig:185 _1+4 ] [185])
(zero_extract:QI (reg:QI 6 r6 [orig:64 a+4 ] [64])
(const_int 1 [0x1])
(const_int 0 [0]))) "bf.c":11:8 985 {*extzvqi_split}
(nil))
(insn 572 16 20 2 (set (mem/c:QI (plus:HI (reg/f:HI 28 r28)
(const_int 1 [0x1])) [4 %sfp+1 S1 A8])
(reg:QI 24 r24 [orig:185 _1+4 ] [185])) "bf.c":11:8 86
{movqi_insn_split}
(nil))
*************************************************************
Insn 13 and insn 572 use sfp+1 as a spill slot, but in IRA pass it was a
two
different pseudos r184 and r185.
Insns 13 use sfp+1 as a spill slot for r184
Insns 572 use the same slot for r185. It's wrong.
Here we have a rematerialization.
Fragment from bf.c.317r.reload:
**************************************************************************************
******** Rematerialization #1: ********
df_worklist_dataflow_doublequeue: n_basic_blocks 14 n_edges 18 count 14 (
1)
df_worklist_dataflow_doublequeue: n_basic_blocks 14 n_edges 18 count 14 (
1)
Cands:
0 (nop=0, remat_regno=185, reload_regno=359):
(insn 16 15 572 2 (set (reg:QI 359 [orig:185 _1+4 ] [185])
(zero_extract:QI (reg:QI 64 [ a+4 ])
(const_int 1 [0x1])
(const_int 0 [0]))) "bf.c":11:8 985
{*extzvqi_split}
(nil))
**************************************************************************************
[...]
**************************************************************************************
Ranges after the compression:
r185: [0..1]
Frame pointer can not be eliminated anymore
Spilling non-eliminable hard regs: 28 29
Spilling r113(28)
Spilling r184(29)
Spilling r208(29)
Spilling r209(28)
Slot 0 regnos (width = 0): 185 209 208 184 113
**************************************************************************************
The bug is here: `r185: [0..1]' wrong live range after compression.
r185 and r184 can't have the same spill slot !
Rematerialization in bf.c.317r.reload looks like:
*************************************************************
24: r14:QI=r185:QI
Inserting rematerialization insn before:
581: r14:QI=zero_extract(r64:QI,0x1,0)
deleting insn with uid = 24.
Considering alt=0 of insn 16: (0) =r (1) rYil (2) n
overall=0,losers=0,rld_nregs=0
32: r22:QI=r185:QI
Inserting rematerialization insn before:
582: r22:QI=zero_extract(r64:QI,0x1,0)
deleting insn with uid = 32.
*************************************************************
It's happened because:
Fragment from lra.c (lra):
*************************************************************************
if (! live_p)
{
/* We need full live info for spilling pseudos into
registers instead of memory. */
lra_create_live_ranges (lra_reg_spill_p, true);
live_p = true;
}
/* We should check necessity for spilling here as the above live
range pass can remove spilled pseudos. */
if (! lra_need_for_spills_p ())
break;
/* Now we know what pseudos should be spilled. Try to
rematerialize them first. */
if (lra_remat ())
{
/* We need full live info -- see the comment above. */
lra_create_live_ranges (lra_reg_spill_p, true);
----------------------------------^^^^^^^^^^^^^^^
live_p = true;
*************************************************************************
The bug is here.
Rematerialization sometimes can be like spilling pseudos into registers.
582: r22:QI=zero_extract(r64:QI,0x1,0)
So, here we need a live ranges for all pseudos.
PS: the patch will not affect any target with usable definition of
TARGET_SPILL_CLASS hook.
PR target/116778
gcc/
* lra-lives.cc (complete_info_p): Clarification of the comment.
* lra.cc (lra): Create a full live info after rematerialization.
More information about the Gcc-bugs
mailing list