This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/86062] Missed redundancy elimination with struct and array
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 06 Jun 2018 09:53:44 +0000
- Subject: [Bug tree-optimization/86062] Missed redundancy elimination with struct and array
- Auto-submitted: auto-generated
- References: <bug-86062-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86062
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2018-06-06
Ever confirmed|0 |1
--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Confirmed. The issue is that when trying to translate MEM[(struct I *)&res +
8B]
through the aggregate copy res = MEM[(const struct I &)&D.25143][1]; we run
into
/* Now re-write REF to be based on the rhs of the assignment. */
copy_reference_ops_from_ref (gimple_assign_rhs1 (def_stmt), &rhs);
/* Apply an extra offset to the inner MEM_REF of the RHS. */
if (maybe_ne (extra_off, 0))
{
if (rhs.length () < 2
|| rhs[0].opcode != MEM_REF
|| known_eq (rhs[0].off, -1))
return (void *)-1;
where the rhs ref is an ARRAY_REF of a MEM_REF. This is a TBAA issue
IIRC (at least when the translated ref would end up in PRE insertion
somehow - PRE doesn't run into this code though).
The following untested fixes it but as said I'm not 100% sure it's safe.
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 4e946ba7baf..4aec41e96c1 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -2270,14 +2270,16 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void
*vr_,
/* Apply an extra offset to the inner MEM_REF of the RHS. */
if (maybe_ne (extra_off, 0))
{
- if (rhs.length () < 2
- || rhs[0].opcode != MEM_REF
- || known_eq (rhs[0].off, -1))
+ if (rhs.length () < 2)
return (void *)-1;
- rhs[0].off += extra_off;
- rhs[0].op0 = int_const_binop (PLUS_EXPR, rhs[0].op0,
- build_int_cst (TREE_TYPE (rhs[0].op0),
- extra_off));
+ int ix = rhs.length () - 2;
+ if (rhs[ix].opcode != MEM_REF
+ || known_eq (rhs[ix].off, -1))
+ return (void *)-1;
+ rhs[ix].off += extra_off;
+ rhs[ix].op0 = int_const_binop (PLUS_EXPR, rhs[ix].op0,
+ build_int_cst (TREE_TYPE
(rhs[ix].op0),
+ extra_off));
}
/* We need to pre-pend vr->operands[0..i] to rhs. */