Commit 78b76d08 by Steven Bosscher Committed by Steven Bosscher

re PR rtl-optimization/25130 (miscompilation in GCSE)

	* fold-const.c (operand_equal_p): Accept a NULL operand 0 for
	COMPONENT_REFs.
	* emit-rtl.c (mem_attrs_htab_eq): Use iterative_hash_expr for
	hashing trees instead of a pointer hash.
	(mem_attrs_htab_eq): Do a deep compare instead of a pointer
	compare for MEM_EXPR.

	PR rtl-optimization/25130
	* cse.c (exp_equiv_p): Compare MEM_ATTRS instead of MEM_ALIAS_SET
	when comparing MEMs for GCSE

From-SVN: r109264
parent 0884546e
2006-01-03 Steven Bosscher <stevenb.gcc@gmail.com>
* fold-const.c (operand_equal_p): Accept a NULL operand 0 for
COMPONENT_REFs.
* emit-rtl.c (mem_attrs_htab_eq): Use iterative_hash_expr for
hashing trees instead of a pointer hash.
(mem_attrs_htab_eq): Do a deep compare instead of a pointer
compare for MEM_EXPR.
PR rtl-optimization/25130
* cse.c (exp_equiv_p): Compare MEM_ATTRS instead of MEM_ALIAS_SET
when comparing MEMs for GCSE
2006-01-03 Ben Elliston <bje@au.ibm.com>
* targhooks.h (default_decimal_float_supported_p): Declare.
......
......@@ -2538,16 +2538,26 @@ exp_equiv_p (rtx x, 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;
......
......@@ -254,7 +254,7 @@ mem_attrs_htab_hash (const void *x)
return (p->alias ^ (p->align * 1000)
^ ((p->offset ? INTVAL (p->offset) : 0) * 50000)
^ ((p->size ? INTVAL (p->size) : 0) * 2500000)
^ (size_t) p->expr);
^ (size_t) iterative_hash_expr (p->expr, 0));
}
/* Returns nonzero if the value represented by X (which is really a
......@@ -267,8 +267,11 @@ mem_attrs_htab_eq (const void *x, const void *y)
mem_attrs *p = (mem_attrs *) x;
mem_attrs *q = (mem_attrs *) y;
return (p->alias == q->alias && p->expr == q->expr && p->offset == q->offset
&& p->size == q->size && p->align == q->align);
return (p->alias == q->alias && p->offset == q->offset
&& p->size == q->size && p->align == q->align
&& (p->expr == q->expr
|| (p->expr != NULL_TREE && q->expr != NULL_TREE
&& operand_equal_p (p->expr, q->expr, 0))));
}
/* Allocate a new mem_attrs structure and insert it into the hash table if
......
......@@ -2635,8 +2635,11 @@ operand_equal_p (tree arg0, tree arg1, unsigned int flags)
&& OP_SAME_WITH_NULL (3));
case COMPONENT_REF:
/* Handle operand 2 the same as for ARRAY_REF. */
return OP_SAME (0) && OP_SAME (1) && OP_SAME_WITH_NULL (2);
/* Handle operand 2 the same as for ARRAY_REF. Operand 0
may be NULL when we're called to compare MEM_EXPRs. */
return OP_SAME_WITH_NULL (0)
&& OP_SAME (1)
&& OP_SAME_WITH_NULL (2);
case BIT_FIELD_REF:
return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);
......
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