<div dir="ltr">Please see inline.<br><div class="gmail_extra"><br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><div>struct S {</div><div>  int a[10];</div><div>  int b;</div><div>};</div><div><br></div><div>int foo(struct S *ps, int i) {</div><div>  ps->a[i] = 1;</div><div>  ps->b = 2;</div><div>  return ps->a[0];</div><div>}</div></div></div><div><div><br></div><div>define i32 @foo(%struct.S* nocapture %ps, i32 %i) #0 {</div><div>entry:</div><div>  %idxprom = sext i32 %i to i64</div><div>  %arrayidx = getelementptr inbounds %struct.S, %struct.S* %ps, i64 0, i32 0, i64 %idxprom</div><div>  store i32 1, i32* %arrayidx, align 4, !tbaa !1</div><div>  %b = getelementptr inbounds %struct.S, %struct.S* %ps, i64 0, i32 1</div><div>  store i32 2, i32* %b, align 4, !tbaa !5</div><div>  %arrayidx2 = getelementptr inbounds %struct.S, %struct.S* %ps, i64 0, i32 0, i64 0</div><div>  %0 = load i32, i32* %arrayidx2, align 4, !tbaa !1</div></div></div></blockquote><div><br></div></span><div>I'm not entirely sure why TBAA is necessary to disambiguate ps->a from ps->b, it looks like basicaa should already be able to say they don't overlap.</div><div>Does this not happen?<br></div></div></div></div></blockquote><div><br></div><div>Opps, you are right in my example basicaaa could do it potentially. Correct example is slightly different:</div><div>int foo(struct S *ps, int i) {<br></div><div><div>  ps->a[i] = 1;</div><div>  ps->b = 2;</div><div>  return ps->a[i];</div><div>}</div></div><div>Here basicaa cannot make sure that 'ps->a[i]' doesn't change after 'ps->b = 2' because if 'i == 10' all 3 memory accesses will read/write the same memory. And type information about S::a is required to disambiguate. With current TBAA 'ps->a[i]' is about random 'int' read.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>Missing information here is the range inside struct S that could be accessed. </div></div></blockquote><div><br></div></span><div>What do you mean by "could be accessed".  Do you mean "valid to access in C"?</div></div></div></div></blockquote><div><br></div><div>By access I meant read/write memory i.e. that size of S::a inside the struct or at least information that only S::a is accessed in this place i.e. not S::b.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>Also as you can see array member of struct in TBAA is presented as omnipotent char not as an array of int.</div></div></blockquote><div><br></div></span><div>Agreed.</div><span class=""><div> </div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div></div><div>Arrays in struct in TBAA can be represented something like this:</div><div>!6 = !{!"S", !7, i64 0, !2, i64 40}<br></div><div><div>!7 = !{!"<unique id of int[10]>", !2, i64 0}</div></div><div><br></div><div>And 'ps->a[i]' could have TBAA like this:</div><div>!8 = !{!6, !7, i64 0}</div></div></blockquote><div><br></div><div><br></div></span><div>Yes. This should likely work. Note that size, while nice, is harder.</div></div></div></div></blockquote><div><br></div><div>Yes, knowledge of size is very good thing but it seems that we can do more even without size. Just using path aware TBAA as we do today but enable it for arrays.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>One thing that is sadly still common (at least in C) is to do this:<br></div><div><br></div><div><div>struct S {</div><div>  int b;<br></div><div>  int a[0]; // or 1</div><div>};</div></div><div><br></div><div>and malloc it at (sizeof S + 40 * sizeof (int)), then write into a[1...39].</div><div><br></div><div><br></div><div>If we want to break that, it is likely a lot of stuff gets broken (at one point when we did it in gcc, we broke 80% of all the packages in a given linux distro ....)</div></div></div></div></blockquote><div><br></div><div>I absolutely agree that we cannot break this. We only can assume that S::b is not accessed via S::s with negative index. As far as I know it shouldn't break good programs.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>As far as I can see if struct is enclosed in another struct, information about inner struct get lost only offset present. But I think for arrays it is better to keep array type in TBAA for the struct and element accesses.<br></div></div></blockquote><div><br></div></span><div>Don't get me wrong, i think that it would be nice to have offset and size, and gcc does indeed track this info on it's own.</div><div><br></div><div>I'm just trying to understand where you think it will provide better info.</div><div><br></div><div>Because once you get into cases like:<br><br></div><div><div><span class=""><div>struct S {</div><div>  int a[10];</div><div>  int b;</div><div>};</div><div><br></div></span><div>int foo(struct S *ps, int *i) {</div><span class=""><div>  ps->a[i] = 1;</div></span><div>  *i = 3;</div><div>  return ps->b;<br></div><div>}</div></div><div><br></div><div>You have no guarantee, for example, that *i and *(ps->b) are not the same memory.</div></div></div></div></div></blockquote><div><br></div><div>Yes, in this example pointer 'i' can point to S:b or S::a so we cannot disambiguate it even with sizes and better TBAA. We need restrict somehere here or information from callgraph to something but it is out of scope TBAA.</div></div></div></div>