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 < ®_eliminate[NUM_ELIMINABLE_REGS]; ep1++)