From d5f7d53546f2b649f60481771bfd889e77b53e78 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Mon, 9 Dec 2013 14:54:00 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++ gcc/config/arm/arm.c | 35 ++++++++++++------- gcc/testsuite/ChangeLog | 4 +++ .../gcc.target/arm/ldrd-strd-offset.c | 17 +++++++++ 4 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/ldrd-strd-offset.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c100cee94ff6..ba39e4b0d363 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2013-12-09 Richard Earnshaw + + * arm.c (mem_ok_for_ldrd_strd): Rename first argument as MEM. Do + more address validation checks. + 2013-12-09 Marek Polacek PR sanitizer/59415 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index c961fb1be2e3..bed24376d1b8 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 5c3e5b55ee90..0f8a9e28a729 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2013-12-09 Richard Earnshaw + + * gcc.target/arm/ldrd-strd-offset.c: New. + 2013-12-09 Martin Jambor * 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 000000000000..a128a0a0e4b2 --- /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; +} -- 2.47.3