[llvm-dev] Aliasing rules difference between GCC and Clang

Jonas Paulsson via llvm-dev llvm-dev at lists.llvm.org
Mon Jan 14 05:57:26 PST 2019


Hi,

It was a while now since I first asked about TBAA, and I am now getting 
back to this, trying to understand TBAA as it seems that the issue I 
described earlier originally in this thread is still one of many "TODO"s 
in CGExpr.cpp 
(http://lists.llvm.org/pipermail/llvm-dev/2018-September/126290.html).

I would like to help on this to the best of my abilities, but I'm not 
quite sure if there is a current plan of incremental changes, or if it 
would be possible to handle the array member of a struct case 
specifically at this point?

I am tempted to believe that the extension to handle my particular case 
is not too far-fetched, as Eli indicated earlier:

This program:

struct A { int i; };
struct B { int i; };

void h(struct A *a, struct B *b, int *prim_i) {
   a->i = 0;
   b->i = 0;
   *prim_i = 0;
}

translates to

%i = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 0
store i32 0, i32* %i, align 4, !tbaa !2
%i1 = getelementptr inbounds %struct.B, %struct.B* %b, i32 0, i32 0
store i32 0, i32* %i1, align 4, !tbaa !7
store i32 0, i32* %prim_i, align 4, !tbaa !9

with this type DAG:

             !2 = !{!3, !4, i64 0}
          !3 = !{!"A", !4, i64 0}
       !4 = !{!"int", !5, i64 0}
    !5 = !{!"omnipotent char", !6, i64 0}
!6 = !{!"Simple C/C++ TBAA"}
             !7 = !{!8, !4, i64 0}
          !8 = !{!"B", !4, i64 0}
          !9 = !{!4, !4, i64 0}

Just as one would hope for, TBAA produces a NoAlias result between the 
stores to %A and %B:

NoAlias:    store i32 0, i32* %i1, align 4, !tbaa !7 <->   store i32 0, 
i32* %i, align 4, !tbaa !2
MayAlias:   store i32 0, i32* %prim_i, align 4, !tbaa !9 <->   store i32 
0, i32* %i, align 4, !tbaa !2
MayAlias:   store i32 0, i32* %prim_i, align 4, !tbaa !9 <->   store i32 
0, i32* %i1, align 4, !tbaa !7

The above indicates that TBAA is capable of handling structs with scalar 
members, but if I change the program to look more like the benchmark, like:

struct A { int i[2]; };
struct B { int i[2]; };

void h(struct A *a, struct B *b, int *prim_i) {
   a->i[0] = 0;
   b->i[0] = 0;
   *prim_i = 0;
}

, which translates to

%i = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 0
%arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %i, i64 0, i64 0
store i32 0, i32* %arrayidx, align 4, !tbaa !2
%i1 = getelementptr inbounds %struct.B, %struct.B* %b, i32 0, i32 0
%arrayidx2 = getelementptr inbounds [2 x i32], [2 x i32]* %i1, i64 0, i64 0
store i32 0, i32* %arrayidx2, align 4, !tbaa !2
store i32 0, i32* %prim_i, align 4, !tbaa !2

, the type DAG is generated as

          !2 = !{!3, !3, i64 0}
       !3 = !{!"int", !4, i64 0}
    !4 = !{!"omnipotent char", !5, i64 0}
!5 = !{!"Simple C/C++ TBAA"}

This makes all the stores alias, which is overly conservative, as 
%struct.A and %struct.B do not alias.

It seems that when the struct member is an array, the base type becomes 
the element type. This is simply unhandled still in CodeGenTBAA 
("TODO"). My question then is if it would be possible to instead create 
the DAG nodes !"A" and !"B" (as in the first type DAG above) and use 
them as the base types and then have the access type to be !"int", with 
the right offset into the struct node?

A struct like

struct S { int i[2]; long l[2]; };

would then be represented with a base node, something like

          !3 = !{!"S", !4, i64 0, !6, 8}
       !4 = !{!"int", !5, i64 0}
    !5 = !{!"omnipotent char", !6, i64 0}
       !6 = !{!"long", !5, i64 0}

, giving !"int" as base at offset 0 and !"long" as base at offset 8 
(given that i[2] is 8 bytes).

An access like s->i[0], would then get a node like

!2 = !{!3, %4, i64 0}

, and this would give a NoAlias above, right? Did I understand this 
correctly, or did I miss anything relevant?

What method(s) would need to be modified to handle this? Is it feasible 
to do this now, or are there other planned steps that somebody is 
working on?

Would this improvement require the NewStructPathTBAA flag to be on, and 
if so, what is the outlook on this?

@Ivan: For what I can see, you had a list of planned improvements. What 
are your thoughts on this?

Thanks for any help,

Jonas



More information about the llvm-dev mailing list