diff mbox

[avr] Fix unrecognizable insn ICE for avr (PR71103)

Message ID 1463147465.21871.11.camel@atmel.com
State New
Headers show

Commit Message

Sivanupandi, Pitchumani May 13, 2016, 1:51 p.m. UTC
avr-gcc crashes for following test as it couldn't recognize the
instruction pattern.

struct st {
  unsigned char uc1;
  unsigned int *ui1;
};

unsigned int ui1;
struct st foo () {
  struct st ret;
  ret.uc1 = 6;
  ret.ui1 = &ui1;
  return ret;
}

$ avr-gcc -mmcu=atmega328p -O1 test.c
(-- snip --) 
test.c: In function 'foo':
test.c:12:1: error: unrecognizable insn:
 }
 ^
(insn 6 5 7 2 (set (subreg:QI (reg:PSI 42 [ D.1499 ]) 1)
        (subreg:QI (symbol_ref:HI ("ui1") <var_decl 0x7f372169e900
ui1>) 0)) test.c:11 -1
     (nil))
test.c:12:1: internal compiler error: in extract_insn, at recog.c:2287
0xd51195 _fatal_insn(char const*, rtx_def const*, char const*, int,
char const*)
    /home/rudran/code/gcc/gcc/rtl-error.c:108
(-- snip --) 

There is no valid pattern in avr to match the "subreg:QI
(symbol_ref:HI)". Attached patch forces the symbol_ref of subreg
operand to register so that it will become register operand and movqi
pattern shall recognize it.

Ran gcc regression test with internal simulators. No new regressions
found.

If ok, could someone commit please?

Regards,
Pitchumani
diff mbox

Patch

diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index c988446..927bc69 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -638,6 +638,13 @@ 
     rtx dest = operands[0];
     rtx src  = avr_eval_addr_attrib (operands[1]);
 
+    if (SUBREG_P(src) && (GET_CODE(XEXP(src,0)) == SYMBOL_REF) &&
+        can_create_pseudo_p())
+      {
+        rtx symbol_ref = XEXP(src, 0);
+        XEXP (src, 0) = copy_to_mode_reg (GET_MODE(symbol_ref), symbol_ref);
+      }
+
     if (avr_mem_flash_p (dest))
       DONE;
 
diff --git a/gcc/testsuite/gcc.target/avr/pr71103.c b/gcc/testsuite/gcc.target/avr/pr71103.c
new file mode 100644
index 0000000..43244d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/pr71103.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+struct ResponseStruct{                                                                                            
+    unsigned char responseLength;
+    char *response;
+};
+
+static char response[5];
+struct ResponseStruct something(){
+    struct ResponseStruct returnValue;
+    returnValue.responseLength = 5;
+    returnValue.response = response;
+    return returnValue;
+}
+