[Bug tree-optimization/63916] New: value-numbering fails to forward variable addresses

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Nov 17 14:59:00 GMT 2014


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63916

            Bug ID: 63916
           Summary: value-numbering fails to forward variable addresses
           Product: gcc
           Version: 5.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rguenth at gcc dot gnu.org

Forwarded from PR59984

---------

That said, even with that, with C it vectorizes fine, while with C++ it
doesn't.

In *.einline the C -> C++ difference is (before that I don't see such):
-  D.1856[_19].x = _24;
-  _26 = &D.1856[_19];
-  _27 = MEM[(const struct XY *)_26].x;
+  D.2352[_19].x = _24;
+  _26 = &D.2352[_19];
+  _40 = MEM[(float *)_26];

In *.ealias the C -> C++ difference is:
-  D.1856[_19].x = _24;
-  _27 = MEM[(const struct XY *)&D.1856][_19].x;
+  D.2352[_19].x = _24;
+  _26 = &D.2352[_19];
+  _40 = MEM[(float *)_26];

and apparently FRE1 handles the former but not the latter.  Richard?
As the struct contains float at that offset, I don't see why FRE1 shouldn't
optimize that to _40 = _24.

Shorter testcase for the FRE1 missed-optimization:
struct S { float a, b; };

float
foo (int x, float y)
{
  struct S z[1024];
  z[x].a = y;
  struct S *p = &z[x];
  float *q = (float *) p;
  return *q;
}

(dunno why the inliner handles things differently between C and C++ on the #c12
testcase).  Now, as for vectorizing it even if FRE isn't able to optimize it,
we currently don't support interleaved accesses to the "omp simd array"
attributed arrays, perhaps we could at least some easy cases thereof, and
supposedly we should teach SRA about those too (like, if the arrays aren't
addressable and aren't accesses as whole, but just individual fields, split it
into separate "omp simd array" accesses instead.  In this particular case due
to the FRE missed optimization it is addressable though.
Or perhaps teach fold to gimple folding to fold that:
  q_5 = &z[x_2(D)];
  _6 = *q_5;
back into:
  _6 = z[x_2(D)].x;
?

--------------

Ok, so SCCVN only can forward constant addresses (because variable ones
wouldn't fit in the same refs vector without "inserting" ops).  See
vn_reference_maybe_forwprop_address.  It's also required so that we can
re-materialize the expression in PRE for example and not wind up with
invalid access paths there (similar to the reason why forwprop doesn't do
this transform).

I think it might be possible to teach SCCVN to do this, but it might be
not trivial.



More information about the Gcc-bugs mailing list