Commit e8024441 by Richard Biener Committed by Richard Biener

re PR rtl-optimization/67443 (DSE removes required store instruction)

2015-10-26  Richard Biener  <rguenther@suse.de>
	Dominik Vogt  <vogt@linux.vnet.ibm.com>

	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 <vogt@linux.vnet.ibm.com>

From-SVN: r229372
parent fec40d06
2015-10-26 Richard Biener <rguenther@suse.de>
Dominik Vogt <vogt@linux.vnet.ibm.com>
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 <richard.sandiford@arm.com>
* gimple-fold.c (replace_stmt_with_simplification): Don't allow
......@@ -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;
......
2015-10-26 Richard Biener <rguenther@suse.de>
Dominik Vogt <vogt@linux.vnet.ibm.com>
PR middle-end/67443
* gcc.target/s390/pr67443.c: New testcase.
2015-10-26 Christophe Lyon <christophe.lyon@linaro.org>
* gfortran.dg/chmod_1.f90: Add suffix to the temporary filename to
......
/* 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 <assert.h>
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment