as Pinski reported at

  https://gcc.gnu.org/ml/gcc-patches/2014-11/msg01967.html

the previosu LR free patch on AArch64 cause one gcc_assert in lra-elimination.c

one of the problem is that gcc_assert is too strict and overkilled some valid 
cases.

the purpose of that assert is described here

  https://gcc.gnu.org/ml/gcc-patches/2013-12/msg00151.html

and I checked the code, it's purpose is to prohibit the following scenario:

  FP decided to be not required earlier, and then be required later.

that assert prohibit above situation, because it will cause bad code 
generation. FP
may be allocated earlier while because later it identified to be required as 
fixed purpose, then
all those pseudo allocated to FP need to be spilled.

so, this check will only make sense when that reg is not fixed itself.

this patch relax that gcc_assert for fixed registers.

the problem reported by Pinski fixed also, because FP of AArch64 is fixed.

bootstrap ok on AArch64 and X86-64.
no regression on X86-64.
Pinskia's testcase passed on AArch64 on his code branch.

ok for trunk?

gcc/
  * lra-eliminations.c (update_reg_eliminate): Relax gcc_assert for fixed 
registers.
diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c
index 8ab0222..aeae27c 100644
--- a/gcc/lra-eliminations.c
+++ b/gcc/lra-eliminations.c
@@ -1199,7 +1199,9 @@ update_reg_eliminate (bitmap insns_with_changed_offsets)
 		     ep->from, ep->to);
 	  /* If after processing RTL we decides that SP can be used as
 	     a result of elimination, it can not be changed.  */
-	  gcc_assert (ep->to_rtx != stack_pointer_rtx);
+	  gcc_assert ((ep->to_rtx != stack_pointer_rtx)
+		      || (ep->from < FIRST_PSEUDO_REGISTER
+			  && fixed_regs [ep->from]));
 	  /* Mark that is not eliminable anymore.  */
 	  elimination_map[ep->from] = NULL;
 	  for (ep1 = ep + 1; ep1 < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep1++)

Reply via email to