]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/49641 (Wrong code for ARMv4T and stmia)
authorRichard Earnshaw <rearnsha@arm.com>
Wed, 16 Nov 2011 17:53:28 +0000 (17:53 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Wed, 16 Nov 2011 17:53:28 +0000 (17:53 +0000)
2011-11-16  Richard Earnshaw  <rearnsha@arm.com>
    Bernd Schmidt <bernds@coudesourcery.com>
    Sebastian Huber <sebastian.huber@embedded-brains.de>

PR target/49641
* config/arm/arm.c (store_multiple_sequence): Avoid cases where
the base reg is stored iff compiling for Thumb1.

* gcc.target/arm/pr49641.c: New test.

Co-Authored-By: Bernd Schmidt <bernds@codesourcery.com>
Co-Authored-By: Sebastian Huber <sebastian.huber@embedded-brains.de>
From-SVN: r181418

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr49641.c [new file with mode: 0644]

index 43a5a72cf66eb801afabbb1badad79d8db8681da..49cc0d2e62223748215b833a688c464a3e97a7c2 100644 (file)
@@ -1,3 +1,11 @@
+2011-11-16  Richard Earnshaw  <rearnsha@arm.com>
+           Bernd Schmidt <bernds@coudesourcery.com>
+           Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+       PR target/49641
+       * config/arm/arm.c (store_multiple_sequence): Avoid cases where
+       the base reg is stored iff compiling for Thumb1.
+
 2011-11-13  Iain Sandoe  <iains@gcc.gnu.org>
 
        PR target/48108
index fcdb8a1814d3ed329831204f707c2cf8f2cada6b..75174a323fa1a16e9abb52a5a91649563ac1ee13 100644 (file)
@@ -9812,6 +9812,9 @@ store_multiple_sequence (rtx *operands, int nops, int nops_total,
   rtx base_reg_rtx = NULL;
   int i, stm_case;
 
+  /* Write back of base register is currently only supported for Thumb 1.  */
+  int base_writeback = TARGET_THUMB1;
+
   /* Can only handle up to MAX_LDM_STM_OPS insns at present, though could be
      easily extended if required.  */
   gcc_assert (nops >= 2 && nops <= MAX_LDM_STM_OPS);
@@ -9869,7 +9872,9 @@ store_multiple_sequence (rtx *operands, int nops, int nops_total,
          /* If it isn't an integer register, then we can't do this.  */
          if (unsorted_regs[i] < 0
              || (TARGET_THUMB1 && unsorted_regs[i] > LAST_LO_REGNUM)
-             || (TARGET_THUMB2 && unsorted_regs[i] == base_reg)
+             /* The effects are unpredictable if the base register is
+                both updated and stored.  */
+             || (base_writeback && unsorted_regs[i] == base_reg)
              || (TARGET_THUMB2 && unsorted_regs[i] == SP_REGNUM)
              || unsorted_regs[i] > 14)
            return 0;
index dd7356c9704137ad9f37d1034fde2142877642af..17a000e5ae3d48edab623e5c37a9be7f7484314c 100644 (file)
@@ -1,3 +1,10 @@
+2011-11-16  Richard Earnshaw  <rearnsha@arm.com>
+           Bernd Schmidt <bernds@coudesourcery.com>
+           Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+       PR target/49641
+       * gcc.target/arm/pr49641.c: New test.
+
 2011-11-10  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/51077
diff --git a/gcc/testsuite/gcc.target/arm/pr49641.c b/gcc/testsuite/gcc.target/arm/pr49641.c
new file mode 100644 (file)
index 0000000..7f9b376
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-mthumb -O2" } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+/* { dg-final { scan-assembler-not "stmia\[\\t \]*r3!\[^\\n]*r3" } } */
+typedef struct {
+  void *t1, *t2, *t3;
+} z;
+extern volatile int y;
+static inline void foo(z *x) {
+  x->t1 = &x->t2;
+  x->t2 = ((void *)0);
+  x->t3 = &x->t1;
+}
+extern z v;
+void bar (void) {
+   y = 0;
+   foo(&v);
+}