From e802444145fa89d9f82a2e5302a324340d0622c9 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 26 Oct 2015 15:24:45 +0000 Subject: [PATCH] re PR rtl-optimization/67443 (DSE removes required store instruction) 2015-10-26 Richard Biener Dominik Vogt PR middle-end/67443 * alias.c (ao_ref_from_mem): Remove promoted subreg handling. Properly prune ref->ref for accesses outside of ref. * gcc.target/s390/pr67443.c: New testcase. Co-Authored-By: Dominik Vogt From-SVN: r229372 --- gcc/ChangeLog | 7 ++++ gcc/alias.c | 15 ++++---- gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gcc.target/s390/pr67443.c | 49 +++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.target/s390/pr67443.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b35b201b0f7..95479f3793a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-10-26 Richard Biener + Dominik Vogt + + PR middle-end/67443 + * alias.c (ao_ref_from_mem): Remove promoted subreg handling. + Properly prune ref->ref for accesses outside of ref. + 2015-10-26 Richard Sandiford * gimple-fold.c (replace_stmt_with_simplification): Don't allow diff --git a/gcc/alias.c b/gcc/alias.c index 1c58547df72..5c1ad34e088 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -339,15 +339,16 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem) || !MEM_SIZE_KNOWN_P (mem)) return true; - /* If the base decl is a parameter we can have negative MEM_OFFSET in - case of promoted subregs on bigendian targets. Trust the MEM_EXPR - here. */ + /* If MEM_OFFSET/MEM_SIZE get us outside of ref->offset/ref->max_size + drop ref->ref. */ if (MEM_OFFSET (mem) < 0 - && (MEM_SIZE (mem) + MEM_OFFSET (mem)) * BITS_PER_UNIT == ref->size) - return true; + || (ref->max_size != -1 + && ((MEM_OFFSET (mem) + MEM_SIZE (mem)) * BITS_PER_UNIT + > ref->max_size))) + ref->ref = NULL_TREE; - /* Otherwise continue and refine size and offset we got from analyzing - MEM_EXPR by using MEM_SIZE and MEM_OFFSET. */ + /* Refine size and offset we got from analyzing MEM_EXPR by using + MEM_SIZE and MEM_OFFSET. */ ref->offset += MEM_OFFSET (mem) * BITS_PER_UNIT; ref->size = MEM_SIZE (mem) * BITS_PER_UNIT; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 73e0a39434a..fd5ade4ac88 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-10-26 Richard Biener + Dominik Vogt + + PR middle-end/67443 + * gcc.target/s390/pr67443.c: New testcase. + 2015-10-26 Christophe Lyon * gfortran.dg/chmod_1.f90: Add suffix to the temporary filename to diff --git a/gcc/testsuite/gcc.target/s390/pr67443.c b/gcc/testsuite/gcc.target/s390/pr67443.c new file mode 100644 index 00000000000..e011a11882f --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr67443.c @@ -0,0 +1,49 @@ +/* Test case for PR/67443. */ + +/* { dg-do run { target s390*-*-* } } */ +/* { dg-prune-output "call-clobbered register used for global register variable" } */ +/* { dg-options "-march=z900 -fPIC -fomit-frame-pointer -O3" } */ + +#include + +/* Block all registers except the first three argument registers. */ +register long r0 asm ("r0"); +register long r1 asm ("r1"); +register long r5 asm ("r5"); +register long r6 asm ("r6"); +register long r7 asm ("r7"); +register long r8 asm ("r8"); +register long r9 asm ("r9"); +register long r10 asm ("r10"); +register long r11 asm ("r11"); + +struct s_t +{ + unsigned f1 : 8; + unsigned f2 : 24; +}; + +__attribute__ ((noinline)) +void foo (struct s_t *ps, int c, int i) +{ + /* Uses r2 as address register. */ + ps->f1 = c; + /* The calculation of the value is so expensive that it's cheaper to spill ps + to the stack and reload it later (into a different register). + ==> Uses r4 as address register.*/ + ps->f2 = i + i % 3; + /* If dead store elimination fails to detect that the address in r2 during + the first assignment is an alias of the address in r4 during the second + assignment, it eliminates the first assignment and the f1 field is not + written (bug). */ +} + +int main (void) +{ + struct s_t s = { 0x01u, 0x020304u }; + + foo (&s, 0, 0); + assert (s.f1 == 0&& s.f2 == 0); + + return 0; +} -- 2.30.2