"then gcc does the right thing in both cases." There is no way it would ever affect execution semantics except through deletion, so ... On Sat, Aug 19, 2017 at 10:54 AM, Ivan A. Kosarev <ikosarev at accesssoftek.com> wrote:> Can you share the snippets you use? > > Reloading x->i may affect performance, but not necessarily execution > semantics.Sure> So if it is not required to reload the value (what I think is true), then > gcc does the right thing in both cases.I'm unsure what you are trying to say here :) The whole point of TBAA is about whether you are eliminate the loads/stores. So yes, gcc is always going to do the right thing, if you believe it's okay to remove the load/stores. That's equivalent to saying "as long as it does nothing or something, it was okay". :) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170819/b21389ec/attachment.html>
Daniel, > The whole point of TBAA is about whether you are > eliminate the loads/stores. So yes, gcc is always > going to do the right thing, if you believe it's okay > to remove the load/stores. > > That's equivalent to saying "as long as it does > nothing or something, it was okay". :) If it eliminates reload where it's not allowed, then wouldn't be okay. In this specific case it does not seem to violate the rules. > Assume we split it as you suggest, > into foo = *x, foo.i and bar = *b, b.a > *x contains a struct containing an int. > *b contains a struct containing a struct > containing an int > " an aggregate or union type that includes one of > the aforementioned types > among its elements or nonstatic > data members (including, recursively, an element or > non-static data member of a subaggregate > or contained union)," > This seems to fall into the "including, recursively" part. The type of (*x) is not compatible with the type of (*b) or, recursively, type of b->i. Similarly, the type of (*b) is not compatible with (*x) or, recursively, x->i. > But, let's assume that is true for a second. > GIven > struct A *a > struct X *x > > a->i > x->i > > Can these accesses alias? Given these definitions: struct A { int i; } *a; struct B { struct A a; } *b; struct X { int i; } *x; No alias. struct X is not compatible with struct A. > struct B *b > struct X *x > > b->a.i > x->i No alias. Same reason. --
On Sat, Aug 19, 2017 at 11:27 AM, Ivan A. Kosarev via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Daniel, > > .... >> the type of (*x) is not compatible with the type of (*b) or, recursively, > type of b->i. Similarly, the type of (*b) is not compatible with (*x) or, > recursively, x->i. > >I'm not sure i'd agree with this.> > But, let's assume that is true for a second. > > GIven > > struct A *a > > struct X *x > > > > a->i > > x->i > > > > Can these accesses alias? > ... >> No alias. struct X is not compatible with struct A. > ... >> No alias. Same reason. > >I think these are interesting interpretations. I'm not sure i'd personally agree with them (and there are definitely compilers out there that do not). It gets more weird with unions. But i'm also not going to say they are unreasonable, because i think the rules are sufficiently subject to reasonable interpretation already. There are things clearly allowed (IE everyone agrees) by the standard that no compiler allows, and things not allowed by the standard that all compilers allow. (See the cerberus reports, which go through this in great detail for C). That said, these interpretations allow significantly more optimization than we allow today, so if users are accepting of them, awesome. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170819/da62362e/attachment.html>