This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/86062] Missed redundancy elimination with struct and array


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.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]