The code was passing a pseudo rather than its allocated hard reg to ira_need_caller_save_p. Running under valgrind to reproduce the failure also showed that ALLOCNO_CROSSED_CALLS_ABIS wasn't being explicitly initialised.
Tested on aarch64-linux-gnu and cross-tested against the testcase on cris-elf. Applied as obvious. Richard 2019-10-01 Richard Sandiford <richard.sandif...@arm.com> gcc/ PR rtl-optimization/91948 * ira-build.c (ira_create_allocno): Initialize ALLOCNO_CROSSED_CALLS_ABIS. * ira-color.c (allocno_reload_assign): Pass hard_regno rather than regno to ira_need_caller_save_p. Index: gcc/ira-build.c =================================================================== --- gcc/ira-build.c 2019-10-01 09:55:35.134088716 +0100 +++ gcc/ira-build.c 2019-10-01 13:55:02.074324628 +0100 @@ -504,6 +504,7 @@ ira_create_allocno (int regno, bool cap_ ALLOCNO_CALL_FREQ (a) = 0; ALLOCNO_CALLS_CROSSED_NUM (a) = 0; ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a) = 0; + ALLOCNO_CROSSED_CALLS_ABIS (a) = 0; CLEAR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a)); #ifdef STACK_REGS ALLOCNO_NO_STACK_REG_P (a) = false; Index: gcc/ira-color.c =================================================================== --- gcc/ira-color.c 2019-09-30 17:20:49.594663967 +0100 +++ gcc/ira-color.c 2019-10-01 13:55:02.074324628 +0100 @@ -4398,7 +4398,7 @@ allocno_reload_assign (ira_allocno_t a, ? ALLOCNO_CLASS_COST (a) : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index [aclass][hard_regno]])); - if (ira_need_caller_save_p (a, regno)) + if (ira_need_caller_save_p (a, hard_regno)) { ira_assert (flag_caller_saves); caller_save_needed = 1;