diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2013-12-09 14:54:00 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@gcc.gnu.org> | 2013-12-09 14:54:00 +0000 |
commit | d5f7d53546f2b649f60481771bfd889e77b53e78 (patch) | |
tree | 107e2ff12362536156d2c89ffbd2cf389777b7e8 | |
parent | e52f6c68f9efea7eb793d168d249cd8ccd86d79f (diff) | |
download | gcc-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
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/ldrd-strd-offset.c | 17 |
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; +} |