]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/61443 ([avr] ICE when varargs argument is indirect addr-space access)
authorGeorg-Johann Lay <avr@gjlay.de>
Thu, 12 Jun 2014 08:20:35 +0000 (08:20 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Thu, 12 Jun 2014 08:20:35 +0000 (08:20 +0000)
gcc/
PR target/61443
* config/avr/avr.md (push<mode>1): Avoid (subreg(mem)) when
loading from address spaces.
gcc/testsuite/
PR target/61443
* gcc.target/avr/torture/pr61443.c: New test.

From-SVN: r211491

gcc/ChangeLog
gcc/config/avr/avr.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/avr/torture/pr61443.c [new file with mode: 0644]

index a8db34b416d94fcfcbacbdc46cee9dab363e59bb..f0d6d26c9c877cbd7437c83d9dd94f98a60e815d 100644 (file)
@@ -1,3 +1,9 @@
+2014-06-12  Georg-Johann Lay  <avr@gjlay.de>
+
+       PR target/61443
+       * config/avr/avr.md (push<mode>1): Avoid (subreg(mem)) when
+       loading from address spaces.
+
 2014-06-12  Martin Liska  <mliska@suse.cz>
 
        PR ipa/61462
index 2c59bf3f93bd3ef34a77ef17eea6177f55f009b8..3bb2a914a339d01d9ccd3247dc2db752975c3fc0 100644 (file)
   ""
   {
     int i;
+
+    // Avoid (subreg (mem)) for non-generic address spaces below.  Because
+    // of the poor addressing capabilities of these spaces it's better to
+    // load them in one chunk.  And it avoids PR61443.
+
+    if (MEM_P (operands[0])
+        && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[0])))
+      operands[0] = copy_to_mode_reg (<MODE>mode, operands[0]);
+
     for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
       {
         rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
index 3e9239545143649fcf21ff17271e2c80ea3082ae..094241acb210ad012f18e47698eba49a5b073235 100644 (file)
@@ -1,3 +1,8 @@
+2014-06-12  Georg-Johann Lay  <avr@gjlay.de>
+
+       PR target/61443
+       * gcc.target/avr/torture/pr61443.c: New test.
+
 2014-06-11  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/19200
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr61443.c b/gcc/testsuite/gcc.target/avr/torture/pr61443.c
new file mode 100644 (file)
index 0000000..12c6bca
--- /dev/null
@@ -0,0 +1,134 @@
+/* { dg-do run } */
+/* { dg-options "-std=gnu99" } */
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#define NC __attribute__((noinline,noclone))
+
+void NC vfun (char n, ...)
+{
+  va_list ap;
+
+  va_start (ap, n);
+
+  switch (n)
+    {
+    default:
+      abort();
+    case 1:
+      if (11 != va_arg (ap, int))
+        abort();
+      break;
+    case 2:
+      if (2222 != va_arg (ap, int))
+        abort();
+      break;
+    case 3:
+      if (333333 != va_arg (ap, __int24))
+        abort();
+      break;
+    case 4:
+      if (44444444 != va_arg (ap, long))
+        abort();
+      break;
+    case 8:
+      if (8888888888888888 != va_arg (ap, long long))
+        abort();
+      break;
+    }
+
+  va_end (ap);
+}
+
+
+void NC boo_qi (const __flash char *p)
+{
+  vfun (1, *p);
+}
+
+void NC boox_qi (const __memx char *p)
+{
+  vfun (1, *p);
+}
+
+void NC boo_hi (const __flash int *p)
+{
+  vfun (2, *p);
+}
+
+void NC boox_hi (const __memx int *p)
+{
+  vfun (2, *p);
+}
+
+void NC boo_psi (const __flash __int24 *p)
+{
+  vfun (3, *p);
+}
+
+void NC boox_psi (const __memx __int24 *p)
+{
+  vfun (3, *p);
+}
+
+void NC boo_si (const __flash long *p)
+{
+  vfun (4, *p);
+}
+
+void NC boox_si (const __memx long *p)
+{
+  vfun (4, *p);
+}
+
+void NC boo_di (const __flash long long *p)
+{
+  vfun (8, *p);
+}
+
+void NC boox_di (const __memx long long *p)
+{
+  vfun (8, *p);
+}
+
+const __flash char f_qi = 11;
+const __flash int f_hi = 2222;
+const __flash __int24 f_psi = 333333;
+const __flash long f_si = 44444444;
+const __flash long long f_di = 8888888888888888;
+
+const __memx char x_qi = 11;
+const __memx int x_hi = 2222;
+const __memx __int24 x_psi = 333333;
+const __memx long x_si = 44444444;
+const __memx long long x_di = 8888888888888888;
+
+char r_qi = 11;
+int r_hi = 2222;
+__int24 r_psi = 333333;
+long r_si = 44444444;
+long long r_di = 8888888888888888;
+
+int main (void)
+{
+  boo_qi (&f_qi);
+  boo_hi (&f_hi);
+  boo_psi (&f_psi);
+  boo_si (&f_si);
+  boo_di (&f_di);
+
+  boox_qi (&x_qi);
+  boox_hi (&x_hi);
+  boox_psi (&x_psi);
+  boox_si (&x_si);
+  boox_di (&x_di);
+
+  boox_qi (&r_qi);
+  boox_hi (&r_hi);
+  boox_psi (&r_psi);
+  boox_si (&r_si);
+  boox_di (&r_di);
+
+  exit (0);
+}