Bug 63916 - value-numbering fails to forward variable addresses
Summary: value-numbering fails to forward variable addresses
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 5.0
: P3 normal
Target Milestone: ---
Assignee: Richard Biener
URL:
Keywords: missed-optimization
Depends on:
Blocks: 66142
  Show dependency treegraph
 
Reported: 2014-11-17 14:59 UTC by Richard Biener
Modified: 2015-06-03 08:02 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-11-17 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2014-11-17 14:59:34 UTC
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.
Comment 1 Richard Biener 2014-11-17 14:59:52 UTC
Mine eventually.
Comment 2 Richard Biener 2015-06-03 08:02:41 UTC
Author: rguenth
Date: Wed Jun  3 08:02:10 2015
New Revision: 224061

URL: https://gcc.gnu.org/viewcvs?rev=224061&root=gcc&view=rev
Log:
2015-06-03  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/63916
	* tree-ssa-sccvn.c (vn_reference_maybe_forwprop_address):
	Forward-propagate non-invariant addresses by splicing their
	reference ops if the result isn't going to be used by PRE.
	(vn_reference_lookup_3): Remove pointless assert.

	* gcc.dg/tree-ssa/ssa-fre-45.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-45.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-sccvn.c
Comment 3 Richard Biener 2015-06-03 08:02:55 UTC
Fixed.