Commit a79761ff authored by jakub's avatar jakub
Browse files

PR rtl-optimization/49390

	Revert:
	2010-06-29  Bernd Schmidt  <bernds@codesourcery.com>

	* cse.c (exp_equiv_p): For MEMs, if for_gcse, only compare
	MEM_ALIAS_SET.

	* gcc.c-torture/execute/pr49390.c: New test.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@175023 138bc75d-0d04-0410-961f-82ee72b054a4
parent 8fe79ba5
2011-06-14 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/49390
Revert:
2010-06-29 Bernd Schmidt <bernds@codesourcery.com>
* cse.c (exp_equiv_p): For MEMs, if for_gcse, only compare
MEM_ALIAS_SET.
2011-06-14 Zdenek Dvorak <ook@ucw.cz>
Tom de Vries <tom@codesourcery.com>
 
......
......@@ -2669,16 +2669,26 @@ exp_equiv_p (const_rtx x, const_rtx y, int validate, bool for_gcse)
case MEM:
if (for_gcse)
{
/* Can't merge two expressions in different alias sets, since we
can decide that the expression is transparent in a block when
it isn't, due to it being set with the different alias set. */
if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
return 0;
/* A volatile mem should not be considered equivalent to any
other. */
if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
return 0;
/* Can't merge two expressions in different alias sets, since we
can decide that the expression is transparent in a block when
it isn't, due to it being set with the different alias set.
Also, can't merge two expressions with different MEM_ATTRS.
They could e.g. be two different entities allocated into the
same space on the stack (see e.g. PR25130). In that case, the
MEM addresses can be the same, even though the two MEMs are
absolutely not equivalent.
But because really all MEM attributes should be the same for
equivalent MEMs, we just use the invariant that MEMs that have
the same attributes share the same mem_attrs data structure. */
if (MEM_ATTRS (x) != MEM_ATTRS (y))
return 0;
}
break;
......
2011-06-14 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/49390
* gcc.c-torture/execute/pr49390.c: New test.
2011-06-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* g++.dg/torture/pr48954.C: Use dg-require-effective-target lto.
......
/* PR rtl-optimization/49390 */
struct S { unsigned int s1; unsigned int s2; };
struct T { unsigned int t1; struct S t2; };
struct U { unsigned short u1; unsigned short u2; };
struct V { struct U v1; struct T v2; };
struct S a;
char *b;
union { char b[64]; struct V v; } u;
volatile int v;
extern void abort (void);
__attribute__((noinline, noclone)) void
foo (int x, void *y, unsigned int z, unsigned int w)
{
if (x != 4 || y != (void *) &u.v.v2)
abort ();
v = z + w;
v = 16384;
}
__attribute__((noinline, noclone)) void
bar (struct S x)
{
v = x.s1;
v = x.s2;
}
__attribute__((noinline, noclone)) int
baz (struct S *x)
{
v = x->s1;
v = x->s2;
v = 0;
return v + 1;
}
__attribute__((noinline, noclone)) void
test (struct S *c)
{
struct T *d;
struct S e = a;
unsigned int f, g;
if (c == 0)
c = &e;
else
{
if (c->s2 % 8192 <= 15 || (8192 - c->s2 % 8192) <= 31)
foo (1, 0, c->s1, c->s2);
}
if (!baz (c))
return;
g = (((struct U *) b)->u2 & 2) ? 32 : __builtin_offsetof (struct V, v2);
f = c->s2 % 8192;
if (f == 0)
{
e.s2 += g;
f = g;
}
else if (f < g)
{
foo (2, 0, c->s1, c->s2);
return;
}
if ((((struct U *) b)->u2 & 1) && f == g)
{
bar (*c);
foo (3, 0, c->s1, c->s2);
return;
}
d = (struct T *) (b + c->s2 % 8192);
if (d->t2.s1 >= c->s1 && (d->t2.s1 != c->s1 || d->t2.s2 >= c->s2))
foo (4, d, c->s1, c->s2);
return;
}
int
main ()
{
struct S *c = 0;
asm ("" : "+r" (c) : "r" (&a));
u.v.v2.t2.s1 = 8192;
b = u.b;
test (c);
if (v != 16384)
abort ();
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