Bug 71627 - AVR error: unable to find a register to spill in class 'POINTER_X_REGS'
Summary: AVR error: unable to find a register to spill in class 'POINTER_X_REGS'
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: other (show other bugs)
Version: 6.1.1
: P3 normal
Target Milestone: 7.0
Assignee: Senthil Kumar Selvaraj
URL:
Keywords: ice-on-invalid-code, ra
Depends on:
Blocks: 56183
  Show dependency treegraph
 
Reported: 2016-06-23 03:51 UTC by Khuong Nguyen Tan
Modified: 2017-01-12 09:32 UTC (History)
1 user (show)

See Also:
Host:
Target: avr
Build:
Known to work: 4.7.2
Known to fail: 4.9.0, 4.9.2, 5.3.0, 6.1.0
Last reconfirmed: 2016-06-27 00:00:00


Attachments
test memx-space (388 bytes, text/x-csrc)
2016-06-23 03:51 UTC, Khuong Nguyen Tan
Details
ice.c: preprocessed C source (148 bytes, text/plain)
2016-06-27 21:02 UTC, Georg-Johann Lay
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Khuong Nguyen Tan 2016-06-23 03:51:22 UTC
Created attachment 38751 [details]
test memx-space

avr-gcc  -mmcu=atmega128 -fdump-rtl-all -o avr.s  -O1 avr.c
avr.c: In function ‘main’:
avr.c:28:1: error: unable to find a register to spill in class ‘POINTER_X_REGS’
 }
 ^
avr.c:28:1: error: this is the insn:
(insn 108 107 109 2 (set (reg:QI 21 r21)
        (subreg:QI (reg/f:PSI 61) 2)) avr.c:22 71 {movqi_insn}
     (nil))
avr.c:28: confused by earlier errors, bailing out
Comment 1 Khuong Nguyen Tan 2016-06-23 03:55:37 UTC
/* { dg-do run } */

/*#include "exit-abort.h"*/
#include <stdio.h>
#define PROGMEM __attribute__((progmem))

const char strA[] PROGMEM = "%ld + %ld + %ld + %ld + %ld = %ld !\n";
//const char strB[] PROGMEM = "%d + %d + %d + %d + %d + %d = %ld !\n";
//const char strA[] PROGMEM = "%c + %c + %c= %c !\n";
//const char strc PROGMEM = 'c';

//volatile __memx const unsigned char s = 1, a='a',b='b',c='c';
//volatile __flash const unsigned char s = 1, a='a',b='b',c='c';
volatile __memx const long  a=24, b=26, c=50, d=23, e=40, f=43;

volatile  long result;
int main()
{
   //char result = 'e'; 
   //printf_P(strB, a, b);
   //printf_P(strC, a);
   result = a + b + c + d + e + f;
   printf_P(strA, a,b,c,d,e,f, result);

   //printf_P("\n==>%c", strc);
   //printf("\nString: %s\n", "End");
   return 0;
}
Comment 2 Georg-Johann Lay 2016-06-27 21:02:45 UTC
Created attachment 38779 [details]
ice.c: preprocessed C source

Confirmed for 4.9.2, 5.2 and 6.1.

Also confirmed for the following test case (no need for headers) with -mmcu=atmega128 -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);
}
Comment 3 Georg-Johann Lay 2016-06-29 11:13:23 UTC
Also confirmed on current trunk.
Comment 4 Senthil Kumar Selvaraj 2016-10-21 11:48:51 UTC
Author: saaadhu
Date: Fri Oct 21 11:48:19 2016
New Revision: 241400

URL: https://gcc.gnu.org/viewcvs?rev=241400&root=gcc&view=rev
Log:
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  <senthil_kumar.selvaraj@atmel.com>

	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  <senthil_kumar.selvaraj@atmel.com>

	PR target/71627
	* gcc.target/avr/pr71627.c: New test

Added:
    trunk/gcc/testsuite/gcc.target/avr/pr71627.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/reload.c
    trunk/gcc/testsuite/ChangeLog
Comment 5 Senthil Kumar Selvaraj 2016-10-24 06:31:10 UTC
Fixed in trunk (7.0)
Comment 6 Khuong Nguyen Tan 2017-01-12 09:32:35 UTC
(In reply to Senthil Kumar Selvaraj from comment #5)
> Fixed in trunk (7.0)

Thanks Senthil Kumar Selvaraj.
It was worked !!