[Bug middle-end/79915] ICE in final_scan_insn, at final.c:2982 (could not split insn) on mips* when compiling libstdc++ with -mlong-calls -mno-abicalls

2017-03-31 Thread mpf at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79915

mpf at gcc dot gnu.org changed:

   What|Removed |Added

 Status|UNCONFIRMED |ASSIGNED
   Last reconfirmed||2017-03-31
 CC||mpf at gcc dot gnu.org
 Ever confirmed|0   |1
  Known to fail||7.0.1

--- Comment #5 from mpf at gcc dot gnu.org ---
This is a bug coming from LRA rematerialisation. The issue is that one or more
LEA64 instructions get rematerialized at a point where there are no other
spills to resolve. Each LEA64 instruction introduces a new scratch which is a
copy of the original scratch but is unallocated. lra_need_for_spills_p says
false in this circumstance but is 'wrong'. One option is to simply go round the
LRA loop one more time (and ensure that the lra_spill code does not assert
because of there being no spills to deal with; it effectively becomes a NOP).
There are plenty of alternative solutions which would involve determining
whether remat introduced any new scratches and only running the loop again in
that situation. We could also optimise to avoid running the lra_spill code as
we really need to get to the top of the loop to re-run assignment I believe.

It almost seems cleaner to continue round the LRA loop after remat and rely on
the single exit point but I assume it was an optimisation to exit immediately
after remat if it resolves all remaining spills.

Vladimir: Is my description detailed enough for you to understand the issue or
should I add dumps as well for a testcase? Is there anything 'safe enough' to
do at this point of release? I'm testing my quick fix as below in case it is a
suitable solution.

diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c
index 492fc18..863136d 100644
--- a/gcc/lra-spills.c
+++ b/gcc/lra-spills.c
@@ -565,7 +565,6 @@ lra_spill (void)
/* We do not want to assign memory for former scratches.  */
&& ! lra_former_scratch_p (i))
   pseudo_regnos[n++] = i;
-  lra_assert (n > 0);
   pseudo_slots = XNEWVEC (struct pseudo_slot, regs_num);
   for (i = FIRST_PSEUDO_REGISTER; i < regs_num; i++)
 {
diff --git a/gcc/lra.c b/gcc/lra.c
index ed1f062..c906d94 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -2490,8 +2490,6 @@ lra (FILE *f)
  /* We need full live info -- see the comment above.  */
  lra_create_live_ranges (lra_reg_spill_p, true);
  live_p = true;
- if (! lra_need_for_spills_p ())
-   break;
}
   lra_spill ();
   /* Assignment of stack slots changes elimination offsets for

[Bug middle-end/79915] ICE in final_scan_insn, at final.c:2982 (could not split insn) on mips* when compiling libstdc++ with -mlong-calls -mno-abicalls

2017-03-07 Thread jan.smets at nokia dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79915

--- Comment #4 from Jan Smets  ---
Created attachment 40910
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40910=edit
testcase pr79951

mips64-linux-gnuabi64-gcc -xc++ pr79951.i -o /dev/null -S -mlong-calls
-mno-abicalls

[Bug middle-end/79915] ICE in final_scan_insn, at final.c:2982 (could not split insn) on mips* when compiling libstdc++ with -mlong-calls -mno-abicalls

2017-03-07 Thread jan.smets at nokia dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79915

Jan Smets  changed:

   What|Removed |Added

 Target|mips|mips64-linux-gnuabi64
Summary|ICE in final_scan_insn, at  |ICE in final_scan_insn, at
   |final.c:2982 on mips when   |final.c:2982 (could not
   |compiling libstdc++ with|split insn) on mips* when
   |-mlong-calls|compiling libstdc++ with
   ||-mlong-calls -mno-abicalls

--- Comment #3 from Jan Smets  ---
And that was because vxworks defaults to -mno-abicalls.

Thus, the example reproduces on mips64-linux with -mno-abicalls