[Bug rtl-optimization/89575] New: LRA for msp430 - Max. number of generated reload insns - frame pointer subreg simplification
jozef.l at mittosystems dot com
gcc-bugzilla@gcc.gnu.org
Mon Mar 4 12:07:00 GMT 2019
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89575
Bug ID: 89575
Summary: LRA for msp430 - Max. number of generated reload insns
- frame pointer subreg simplification
Product: gcc
Version: 9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: jozef.l at mittosystems dot com
Target Milestone: ---
Created attachment 45881
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45881&action=edit
testcase
When enabling LRA for msp430, libgcc fails to build, specifically _muldi3.o.
> gcc -S tester.i -O2
> during RTL pass: reload
> ../../../../libgcc/libgcc2.c: In function '__muldi3':
> ../../../../libgcc/libgcc2.c:558:1: internal compiler error: Max. number of generated reload insns per insn is achieved (90)
>
> 558 | }
> | ^
> 0xa2ab20 lra_constraints(bool)
> ../../gcc/lra-constraints.c:4875
> 0xa12b84 lra(_IO_FILE*)
> ../../gcc/lra.c:2461
> 0x9c68f1 do_reload
> ../../gcc/ira.c:5516
> 0x9c68f1 execute
> ../../gcc/ira.c:5700
The cycling reload occurs because IRA assigns hard register R4 (also
FRAME_POINTER_REGNUM, but not fixed for this use) to a pseudo reg, but when LRA
goes to simplify a subreg of the pseudo, it disallows simplification of this
subreg.
Specifically, simplify_subreg_regno (rtlanal.c):
> /* We shouldn't simplify stack-related registers. */
> if ((!reload_completed || frame_pointer_needed)
> && xregno == FRAME_POINTER_REGNUM)
> return -1;
This is in an output reload, so a new set of mov insns are generated to load
the value back into the original, problematic pseudo of R4. Once again
simplify_subreg_regno is called to simplify the pseudo of R4, but it is
disallowed and the cycle continues.
From the IRA dump:
> Disposition:
> 0:r28 l0 8 2:r30 l0 4 1:r31 l0 4
> ...
> (insn 2 6 3 2 (set (subreg:HI (reg/v:DI 30 [ arg1 ]) 0)
> (reg:HI 12 R12 [ arg1 ])) "tester.c":16:1 12 {movhi}
> (expr_list:REG_DEAD (reg:HI 12 R12 [ arg1 ])
> (nil)))
From the reload dump:
> Creating newreg=37 from oldreg=30, assigning class NO_REGS to subreg reg r37
> 2: r37:DI#0=R12:HI
> ...
> Inserting subreg reload after:
> 42: r30:DI#0=r37:DI#0
> ...
> Creating newreg=38 from oldreg=30, assigning class NO_REGS to subreg reg r38
> 42: r38:DI#0=r37:DI#0
> ...
> Inserting subreg reload after:
> 52: r30:DI#0=r38:DI#0
And so on.
Is it OK to allow simplification of a subreg of FRAME_POINTER_REGNUM
when lra_in_progress is true? After all, constraints on the allocation of hard
regs shouldn't get more resitrictive as compilation progresses?
e.g.
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 3873b4098b0..9700928ff4e 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -3971,7 +3971,7 @@ simplify_subreg_regno (unsigned int xregno, machine_mode
xmode,
return -1;
/* We shouldn't simplify stack-related registers. */
- if ((!reload_completed || frame_pointer_needed)
+ if ((!(reload_completed || lra_in_progress) || frame_pointer_needed)
&& xregno == FRAME_POINTER_REGNUM)
return -1;
This fixes the cycling reload for insn 2, as the frame pointer is not needed,
but there are further separate issues building the test case.
I've attached a reduced test case, and the IRA and reload dumps.
> gcc -v
> Target: msp430-elf
> Configured with: ../configure --target=msp430-elf --disable-nls --enable-languages=c,c++
> Thread model: single
> gcc version 9.0.1 20190301 (experimental) (GCC)
More information about the Gcc-bugs
mailing list