aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2013-12-09 14:54:00 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2013-12-09 14:54:00 +0000
commitd5f7d53546f2b649f60481771bfd889e77b53e78 (patch)
tree107e2ff12362536156d2c89ffbd2cf389777b7e8 /gcc
parente52f6c68f9efea7eb793d168d249cd8ccd86d79f (diff)
downloadgcc-d5f7d53546f2b649f60481771bfd889e77b53e78.zip
gcc-d5f7d53546f2b649f60481771bfd889e77b53e78.tar.gz
gcc-d5f7d53546f2b649f60481771bfd889e77b53e78.tar.bz2
re PR rtl-optimization/54300 (regcprop incorrectly looks through parallel register swap operation)
PR rtl-optimization/54300 gcc/ PR rtl-optimization/54300 * regcprop.c (copyprop_hardreg_forward_1): Ensure any unused outputs in a single-set are killed from the value chains. gcc/testsuite: PR rtl-optimization/54300 * gcc.target/arm/pr54300.C: New test. From-SVN: r205807
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/arm/arm.c35
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/arm/ldrd-strd-offset.c17
4 files changed, 48 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c100cee..ba39e4b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2013-12-09 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (mem_ok_for_ldrd_strd): Rename first argument as MEM. Do
+ more address validation checks.
+
2013-12-09 Marek Polacek <polacek@redhat.com>
PR sanitizer/59415
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index c961fb1..bed2437 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -15285,28 +15285,37 @@ operands_ok_ldrd_strd (rtx rt, rtx rt2, rtx rn, HOST_WIDE_INT offset,
}
/* Helper for gen_operands_ldrd_strd. Returns true iff the memory
- operand ADDR is an immediate offset from the base register and is
- not volatile, in which case it sets BASE and OFFSET
- accordingly. */
-bool
-mem_ok_for_ldrd_strd (rtx addr, rtx *base, rtx *offset)
+ operand MEM's address contains an immediate offset from the base
+ register and has no side effects, in which case it sets BASE and
+ OFFSET accordingly. */
+static bool
+mem_ok_for_ldrd_strd (rtx mem, rtx *base, rtx *offset)
{
+ rtx addr;
+
+ gcc_assert (base != NULL && offset != NULL);
+
/* TODO: Handle more general memory operand patterns, such as
PRE_DEC and PRE_INC. */
- /* Convert a subreg of mem into mem itself. */
- if (GET_CODE (addr) == SUBREG)
- addr = alter_subreg (&addr, true);
-
- gcc_assert (MEM_P (addr));
+ if (side_effects_p (mem))
+ return false;
- /* Don't modify volatile memory accesses. */
- if (MEM_VOLATILE_P (addr))
+ /* Can't deal with subregs. */
+ if (GET_CODE (mem) == SUBREG)
return false;
+ gcc_assert (MEM_P (mem));
+
*offset = const0_rtx;
- addr = XEXP (addr, 0);
+ addr = XEXP (mem, 0);
+
+ /* If addr isn't valid for DImode, then we can't handle it. */
+ if (!arm_legitimate_address_p (DImode, addr,
+ reload_in_progress || reload_completed))
+ return false;
+
if (REG_P (addr))
{
*base = addr;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5c3e5b5..0f8a9e2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2013-12-09 Richard Earnshaw <rearnsha@arm.com>
+
+ * gcc.target/arm/ldrd-strd-offset.c: New.
+
2013-12-09 Martin Jambor <mjambor@suse.cz>
* gcc.c-torture/compile/pr39834.c: Remove optimization level option.
diff --git a/gcc/testsuite/gcc.target/arm/ldrd-strd-offset.c b/gcc/testsuite/gcc.target/arm/ldrd-strd-offset.c
new file mode 100644
index 0000000..a128a0a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/ldrd-strd-offset.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef struct
+{
+ int x;
+ int i, j;
+} off_struct;
+
+int foo (char *str, int *a, int b, int c)
+{
+ off_struct *p = (off_struct *)(str + 3);
+ b = p->i;
+ c = p->j;
+ *a = b + c;
+ return 0;
+}