[llvm-dev] RFC: Resolving TBAA issues

Ivan A. Kosarev via llvm-dev llvm-dev at lists.llvm.org
Sun Aug 20 02:47:41 PDT 2017


Hello 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 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).
 >>
 >> I wonder how you know that those compilers interpret it
 >> differently. If the correct answer for a specific case is
 >> "no alias", then reloading of values does not say anything
 >> about how authors interpret the cited clause.
 >>
 >> It's only omission of reloading that does matter.
 >
 > I know how to produce internal pass dump files and debug output
 > from a lot of compilers (XLC, ICC, GCC, etc)
 > So i'm staring at the debug output  to see what it says.

Sorry, what I'm trying to determine here is whether observed facts 
contradict with either or both of the interpretations. I would 
appreciate if you can help me with this so once it is settled, we can 
proceed with resolving outstanding TBAA issues.

So once again, if for a specific case the correct answer is "no alias", 
then how you know by looking at the generated code, dump files and debug 
output what way the authors interpret the clause?

You said that there are compilers that definitely do not agree with that 
'a->i' and 'b->i' may not overlap if the types of (*a) and (*b) are not 
compatible. Can we know how you came to this conclusion? Can you provide 
specific examples?

 > It's not clear GCC agrees with my interpretation. I can get it
 > to seem to answer both ways.

Let's consider this as a specific example:

https://bugs.llvm.org/show_bug.cgi?id=8572

and keeping in mind your experience:

 > Also, in the case of GCC specifically, i wrote a large amount
 > of it's current aliasing infrastructure, so i have scripts to
 > use the debugger to print out the tbaa tree nicely from the
 > in-memory structure.

Do you treat that gcc behavior as intentional or a bug? Do you think we 
should file a defect report and ask gcc developers to fix it so that the 
code like this shall preserve its cycles?

 >> These two accesses are allowed overlap as the type of b->a is
 >> compatible with the type of (*x).
 >
 > Errr, previously you split the access into one, and said it's
 > about whether each part is compatible.
 > So i assume then you also believe *b is compatible with *x
 > here?

Let me repeat the example:

   struct A { int i; } *x;
   struct B { struct A a; } *b;

   b->a
   x->i

And the wording:

   An object shall have its stored value accessed only by an
   lvalue expression that has one of the following types:
   - a type compatible with the effective type of the object,
   - a qualified version of a type compatible with the effective
     type of the object,
   - a type that is the signed or unsigned type corresponding to
     the effective type of the object,
   - a type that is the signed or unsigned type corresponding to a
     qualified version of the effective type of the object,
   - an aggregate or union type that includes one of the
     aforementioned types among its members (including,
     recursively, a member of a subaggregate or contained union),
     or
   - a character type.

The answer to your question is: (*b) need not to be compatible with (*x) 
for accesses b->a and x->i to be allowed to overlap, because the type of 
(*b) is an aggregate that includes the type of (*x) among its members, 
which is exactly what the Standard says.

Here's the full analysis: B is not compatible with A or A::i. And A is 
not compatible with B, but it is compatible with B::a.

Now back you your previous examples:

   struct A { int i; } *a;
   struct B { struct A a; } *b;

   struct X { int i; } *x;

   a->i
   x->i

Here A is not compatible with X or X::i and X is not compatible with A 
or A::i. Therefore, no alias.

   b->a.i
   x->i

B is not compatible with X or X::i and X is not compatible with B, B::a 
or B::a::i. No alias.

Now,

 > I don't find your answers that consistent with the rules.

can you tell me what exactly looks inconsistent in the analysis of these 
three cases?

Also, I wonder what makes you thinking that by lvalue access in this 
quote we should mean only the final lvalue access? How any other lvalues 
accesses are different?

 > I do not feel you have explained *why* you find these types
 > "incompatible" (the rules only talk about direct compatibility
 > as one option).
 > You have just asserted they are so.

Can you expand on this? Which of these three types A, B and X you 
think/suspect are compatible and why?

Thanks,

-- 



More information about the llvm-dev mailing list