/* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-fre1-details" } */
+/* { dg-options "-O -fno-tree-sra -fdump-tree-fre1-details" } */
struct Foo {
Foo() {};
}
/* { dg-final { scan-tree-dump "Replaced b1.b with 1" "fre1" } } */
-/* { dg-final { scan-tree-dump "Replaced b1.i with 0" "fre1" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump "Replaced b1.f with 1" "fre1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "Replaced b1.D.\[0-9\]*.i with 0" "fre1" } } */
+/* { dg-final { scan-tree-dump "Replaced b1.D.\[0-9\]*.f with 1" "fre1" } } */
/* { dg-final { cleanup-tree-dump "fre1" } } */
{
VEC (vn_reference_op_s, heap) *tem;
tree lhs = gimple_assign_lhs (def_stmt);
+ bool valueized_anything = false;
/* Avoid re-allocation overhead. */
VEC_truncate (vn_reference_op_s, lhs_ops, 0);
copy_reference_ops_from_ref (lhs, &lhs_ops);
tem = lhs_ops;
- lhs_ops = valueize_refs (lhs_ops);
+ lhs_ops = valueize_refs_1 (lhs_ops, &valueized_anything);
gcc_assert (lhs_ops == tem);
- lhs_ref_ok = ao_ref_init_from_vn_reference (&lhs_ref, get_alias_set (lhs),
- TREE_TYPE (lhs), lhs_ops);
- if (lhs_ref_ok
- && !refs_may_alias_p_1 (ref, &lhs_ref, true))
- return NULL;
+ if (valueized_anything)
+ {
+ lhs_ref_ok = ao_ref_init_from_vn_reference (&lhs_ref,
+ get_alias_set (lhs),
+ TREE_TYPE (lhs), lhs_ops);
+ if (lhs_ref_ok
+ && !refs_may_alias_p_1 (ref, &lhs_ref, true))
+ return NULL;
+ }
+ else
+ {
+ ao_ref_init (&lhs_ref, lhs);
+ lhs_ref_ok = true;
+ }
}
base = ao_ref_base (ref);
j--;
}
+ /* ??? The innermost op should always be a MEM_REF and we already
+ checked that the assignment to the lhs kills vr. Thus for
+ aggregate copies using char[] types the vn_reference_op_eq
+ may fail when comparing types for compatibility. But we really
+ don't care here - further lookups with the rewritten operands
+ will simply fail if we messed up types too badly. */
+ if (j == 0 && i == 0
+ && VEC_index (vn_reference_op_s, lhs_ops, 0)->opcode == MEM_REF
+ && VEC_index (vn_reference_op_s, vr->operands, i)->opcode == MEM_REF
+ && tree_int_cst_equal
+ (VEC_index (vn_reference_op_s, lhs_ops, 0)->op0,
+ VEC_index (vn_reference_op_s, vr->operands, i)->op0))
+ i--, j--;
+
/* i now points to the first additional op.
??? LHS may not be completely contained in VR, one or more
VIEW_CONVERT_EXPRs could be in its way. We could at least