aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2011-11-16 17:02:44 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2011-11-16 17:02:44 +0000
commit77b1138b71b96989ec25521a19a4afc6f968227d (patch)
tree40c993e2c788c6a07c472cfc5ae12c96ea68853f
parent3b04e1e4c42c56f2c276e8480e80391451dbe5fc (diff)
downloadgcc-77b1138b71b96989ec25521a19a4afc6f968227d.zip
gcc-77b1138b71b96989ec25521a19a4afc6f968227d.tar.gz
gcc-77b1138b71b96989ec25521a19a4afc6f968227d.tar.bz2
re PR target/49641 (Wrong code for ARMv4T and stmia)
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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/arm/arm.c7
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.target/arm/pr49641.c18
4 files changed, 39 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f787912..7bb2b60 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 6ef6f62..4846d72 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d045045..a6e3259 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
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);
+}