Hello,

what about the attached patch based on the original patch provided by Bernd Schmidt with modifications suggested by Richard Earnshaw.

--
Sebastian Huber, embedded brains GmbH

Address : Obere Lagerstr. 30, D-82178 Puchheim, Germany
Phone   : +49 89 18 90 80 79-6
Fax     : +49 89 18 90 80 79-9
E-Mail  : sebastian.hu...@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
	* 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.

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index fcdb8a1..63b5a8b 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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;
diff --git a/gcc/testsuite/gcc.target/arm/pr49641.c b/gcc/testsuite/gcc.target/arm/pr49641.c
new file mode 100644
index 0000000..7f9b376
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr49641.c
@@ -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);
+}

Reply via email to