On Tue, Oct 4, 2011 at 3:28 PM, Jakub Jelinek <ja...@redhat.com> wrote: > On Tue, Oct 04, 2011 at 01:55:27PM +0200, Michael Matz wrote: >> Ugh, that's stretching our fragile to unsafe restrict support quite much. >> IMO beyond what we can reasonably be confident to not cause >> miscompilations. Essentially what you're implicitely assuming is that the >> sources of restrict tags can ultimately be memory, and that this is >> somehow reliable. It unfortunately isn't. > > If it causes miscompilations, then GCC is buggy and needs to be fixed. > restrict structure fields are not some kind of extension, they are in ISO > C99, see 6.7.3/12). > >> Keep in mind that the whole current restrict-tag support was designed to >> support fortrans specific needs where we can rely on the compiler >> generating code we most probably (!) won't miscompile later. Further we >> interpret some of the part where ISO-C says nothing in our favor. >> Together this means that e.g. (intentionally _not_ ISO-C, but sort of >> middle-end speak): >> >> foo (struct s) >> { restrict int *p1 = s.p; >> restrict int *p2 = s.p; >> *p1 = 0; *p2 = 1; return *p1; >> } > > Not sure what you mean here. restrict int doesn't make sense, > int *restrict p1 would make sense, but then it would be invalid C. > >> So, loads generate new tags, and we rely on optimizations that this >> doesn't cause miscompilations via invalid disambiguations, which works >> fine for the restricted set of cases coming from the fortran frontend. > > Loads don't generate new tags. > Try: > struct S { int a; int *__restrict p; }; > > int *a, *b, *c, *d; > > void > foo (S x, S &__restrict y, int z) > { > if (z > 64) > { > a = x.p; > b = y.p; > x.p[z] = y.p[z]; > } > else if (z < 20) > { > c = x.p; > d = y.p; > y.p[z] = x.p[z]; > } > } > > Both the pointers loaded from x.p will have the same heap var in PT info, > similarly both pointers loaded from y.p will have the same heap var in PT > info.
You are right - we currently restrict ourselves to restrict tag generation from memory on parameters and globals to avoid the situation to rely on optimization. Which is why struct S { int * restrict p; }; void foo (int *q) { struct S s; s.p = q; int * restrict x = s.p; *x = 1; } does not get you a restrict tag for s.p but only for the conversion of q before the store to s.p (this tag is propagated to x though). Basically restrict tag generation happens at the time we generate the internal PTA representation for 'memory' which happens once for each 'memory' we can name (and not for memory we can't name, apart from DECL_BY_REFERENCE restrict-qualified parameters). Conversions OTOH are a source of restrict (I added this to not lose restrict information during inlining as we'd keep the casts to the argument types), which ultimately is the reason for PR48764 and PR49279 ... > I don't see how my patch could make things worse then they already are. I still have to have a detailled look at the patch. Richard.