re PR target/49641 (Wrong code for ARMv4T and stmia)
authorRichard Earnshaw <rearnsha@arm.com>
Wed, 16 Nov 2011 17:02:44 +0000 (17:02 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Wed, 16 Nov 2011 17:02:44 +0000 (17:02 +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: r181416

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

index f787912a5a1b190ff97c566b4fc2ce694df0c401..7bb2b600804a7ad7a42c899cc19a470f136201d9 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-16  Razya Ladelsky  <razya@il.ibm.com>
        
        PR tree-optimization/49960
index 6ef6f62d28d0bea798cf314f9b141b7dd8d25308..4846d7277f5ad19d47541e7de41c4e051aa8d727 100644 (file)
@@ -10247,6 +10247,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);
@@ -10304,7 +10307,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 d045045cfd2870095308d4899d27515e66957d3b..a6e32596f7048a7a32293d88bd03baa67acdb45e 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-16  Razya Ladelsky  <razya@il.ibm.com>
 
         PR tree-optimization/49960
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);
+}