From: Senthil Kumar Selvaraj Date: Fri, 21 Oct 2016 11:48:19 +0000 (+0000) Subject: Fix PR 71627 - unable to find a register to spill X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1d64ceb0579f2da8fec5f26932d5b182653c60d7;p=gcc.git Fix PR 71627 - unable to find a register to spill Tweak find_valid_class_1 to consider a reg class if atleast one regno in that class is ok. Previously, even if no regno was in_hard_reg_set_p, the code goes ahead and considers rclass as valid. bad was set only if a regno was in the reg class *and* HARD_REGNO_MODE_OK was false - if both were false, bad wasn't set and the reload got a wrong rclass. If that happened to be the best one, this eventually lead to find_reg running out of registers to spill, because the chosen rclass wouldn't have enough regs. Also, it expected every regno in rclass to be valid for mode i.e., if any regno fails HARD_REGNO_MODE_OK, it rejected the rclass. The comments in the original commit for find_valid_class_1 say atleast one regno is ok. This was updated to say "class which contains only registers" when in_hard_reg_set_p was introduced in place of just TEST_HARD_REG_BIT. This commit fixes both of the above problems by not breaking out of the loop on first unavailable regno. Instead, it computes the rclass size consisting of all regnos in that class valid for the current mode. If that computed size is zero, the rclass would be skipped, as it won't beat best_size. Otherwise, the computed size is used to choose the best rclass, instead of the static size from reg_class_size. gcc/ 2016-10-21 Senthil Kumar Selvaraj PR target/71627 * reload.c (find_valid_class_1): Allow regclass if atleast one regno in regclass is ok. Compute and use rclass size based on actually available regnos for mode in rclass. gcc/testsuite/ 2016-10-21 Senthil Kumar Selvaraj PR target/71627 * gcc.target/avr/pr71627.c: New test From-SVN: r241400 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 66f78be9b99..8f7a1b0cb25 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-10-21 Senthil Kumar Selvaraj + + PR target/71627 + * reload.c (find_valid_class_1): Allow regclass if atleast one + regno in regclass is ok. Compute and use rclass size based on + actually available regnos for mode in rclass. + 2016-10-21 Eric Botcazou * config/sparc/sparc-modes.def (CCV): New. diff --git a/gcc/reload.c b/gcc/reload.c index 9a859e5b45b..651755298ab 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -715,25 +715,23 @@ find_valid_class_1 (machine_mode outer ATTRIBUTE_UNUSED, for (rclass = 1; rclass < N_REG_CLASSES; rclass++) { - int bad = 0; - for (regno = 0; regno < FIRST_PSEUDO_REGISTER && !bad; regno++) - { - if (in_hard_reg_set_p (reg_class_contents[rclass], mode, regno) - && !HARD_REGNO_MODE_OK (regno, mode)) - bad = 1; - } - - if (bad) - continue; + unsigned int computed_rclass_size = 0; + + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + { + if (in_hard_reg_set_p (reg_class_contents[rclass], mode, regno) + && (HARD_REGNO_MODE_OK (regno, mode))) + computed_rclass_size++; + } cost = register_move_cost (outer, (enum reg_class) rclass, dest_class); - if ((reg_class_size[rclass] > best_size + if ((computed_rclass_size > best_size && (best_cost < 0 || best_cost >= cost)) || best_cost > cost) { best_class = (enum reg_class) rclass; - best_size = reg_class_size[rclass]; + best_size = computed_rclass_size; best_cost = register_move_cost (outer, (enum reg_class) rclass, dest_class); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0e32435bba4..771daa35ba3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-10-21 Senthil Kumar Selvaraj + + PR target/71627 + * gcc.target/avr/pr71627.c: New test + 2016-10-21 Eric Botcazou * gcc.target/sparc/overflow-1.c: New test. diff --git a/gcc/testsuite/gcc.target/avr/pr71627.c b/gcc/testsuite/gcc.target/avr/pr71627.c new file mode 100644 index 00000000000..eaef3d20863 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/pr71627.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + + +extern volatile __memx const long a, b, c, d, e, f; +extern volatile long result; + +extern void vfunc (const char*, ...); + +void foo (void) +{ + result = a + b + c + d + e + f; + vfunc ("text", a, b, c, d, e, f, result); +}