[PATCH] D26831: [LangRef] Update the TBAA section

Sanjoy Das via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 15 18:28:29 PST 2016

sanjoy added inline comments.

Comment at: docs/LangRef.rst:4494-4496
+structured in a way that for every access tag ``(BaseTy, AccessTy,
+Offset)``, ``GetAliasingLocations((BaseTy, AccessTy, Offset))`` contains
+``(AccessTy, AccessTy, 0)``.
anna wrote:
> Could you please explain why this is needed? 
I don't want to get into the details in the LangRef (the section is already quite large now), but this requirement stems from `MDNode::getMostGenericTBAA`.  It takes two struct tags as arguments `(StructA, ScalarA, OffsetA)` and `(StructB, ScalarB, OffsetB)` and first "coarsens" them to `(ScalarA, ScalarA, OffsetA)` and `(ScalarB, ScalarB, OffsetB)`.  It then tries to find a common alias tag for `(ScalarA, ScalarA, OffsetA)` and `(ScalarB, ScalarB, OffsetB)`.  The first step is wrong if `(ScalarA, ScalarA, OffsetA)` does not alias `(StructA, ScalarA, OffsetA)` (same for the other one) since then that step won't be a "coarsening" any more, and we'd go from aliasing some set of locations to aliasing a different set of locations, and the final result will be wrong.

As an example, say we have:

struct A {
  float f;
  int i;

and I want to compute the most generic metadata for the two accesses `a.f = ..` and `a.i = ..`.

In the correct case, `a.f` will be tagged with `(A, float, 0)` and `a.i` will be tagged with `(A, int, 4)`.  `getMostGenericTBAA` will coarsen these to `(float, float, 0)` (i.e. any `float` access) and `(int, int 0)` (i.e. any `int` access) and will eventually resolve them to a common `(char, char, 0)` tag, which in C means it basically aliases with everything since `char` can be used to access locations of any type.  In particular, it aliases with both the tags for `a.i` and `a.f`.

Now say we make a mistake, and tag `a.i` with `(A, float, 4)` (and `a.f` is the same).  `getMostGenericTBAA` will resolve these to a common `(float, float, 0)` tag.  However, `(float, float, 0)` does not alias with the incorrect tag for `a.i` (by the rules stated in `GetAliasingLocations`), which is wrong -- we wanted a tag that aliases both `a.f` and `a.i`.

Comment at: docs/LangRef.rst:4546-4547
-    !0 = !{ !"an example type tree" }
-    !1 = !{ !"int", !0 }
-    !2 = !{ !"float", !0 }
-    !3 = !{ !"const float", !2, i64 1 }
-The first field is an identity field. It can be any value, usually a
-metadata string, which uniquely identifies the type. The most important
-name in the tree is the name of the root node. Two trees with different
-root node names are entirely disjoint, even if they have leaves with
-common names.
-The second field identifies the type's parent node in the tree, or is
-null or omitted for a root node. A type is considered to alias all of
-its descendants and all of its ancestors in the tree. Also, a type is
-considered to alias all types in other trees, so that bitcode produced
-from multiple front-ends is handled conservatively.
-If the third field is present, it's an integer which if equal to 1
-indicates that the type is "constant" (meaning
+``GetAliasingLocations(tag3)`` is ``{tag3, tag4, tag7, (CharScalarTy,
+IntScalarTy, 0)}``.  This means that ,other than ``tag3`` itself, ``tag3``
+aliases ``tag4``, ``tag7`` and ``tag8``, reflecting the fact that
anna wrote:
> The mandatory `(AccessTy, AccessTy, 0)` for the result of `GetAliasingLocations(tag3)`refers to `(CharScalarTy, IntScalarTy, 0)` right? 
> Can we have more than 2 `AccessTy`?
These are tuples, and I'm showing the output of `GetAliasingLocations`


More information about the llvm-commits mailing list