<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 20, 2015 at 12:27 PM, Ahmed Bougacha <span dir="ltr"><<a href="mailto:ahmed.bougacha@gmail.com" target="_blank">ahmed.bougacha@gmail.com</a>></span> wrote:<br><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 id=":ehp" class="" style="overflow:hidden">Hi all,<br>
<br>
This is covered by (struct-path aware) TBAA, but BasicAA disagrees.<br>
See the attached testcase, where it prevents us from removing the<br>
redundant load.<br>
For arbitrary GEPs, we can't decide based on constant indices (because<br>
of e.g., &A[0][1] and &A[1][0], with *A a one-element array). BasicAA<br>
has some logic to "try to distinguish something like &A[i][1] against<br>
&A[42][0]". For the testcase, it works for instance when the struct<br>
has an even number of floats.<br>
<br>
However, I think we can safely say GEPs with different constant<br>
indices into a struct can't alias, at least when:<br>
- the GEP is inbounds<br></div></blockquote><div><br></div><div>I'm afraid that this is irrelevant. The only property conferred by inbounds is that none of the intermediate pointers fall outside the allocated object. It has nothing to do with indexing past the bounds (in either positive or negative directions) of an array element within a struct. See <a href="http://llvm.org/docs/GetElementPtr.html#what-happens-if-an-array-index-is-out-of-bounds">http://llvm.org/docs/GetElementPtr.html#what-happens-if-an-array-index-is-out-of-bounds</a> and the immediately following entry.</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 id=":ehp" class="" style="overflow:hidden">
- the access sizes are such that there is no overlap<br></div></blockquote><div><br></div><div>I think this is what you have to prove, and once you do</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 id=":ehp" class="" style="overflow:hidden">- the struct index is the final one<br></div></blockquote><div><br></div><div>I think this stops mattering.</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 id=":ehp" class="" style="overflow:hidden">
<br>
That is, these can't alias:<br>
gep i1, j1, k1, 0<br>
gep i2, j2, k2, 1<br>
If this is a struct pointer:<br>
gep i1, j1, k1 </div></blockquote><div><br></div><div>I don't think this holds in general... Consider the type which contains 4 i32 objects: { [1 x { i32, i32 }], [2 x { i32 }] }.</div><div><br></div><div>A) gep 0, 1, 1, 0 -> points at the 4th i32 object</div><div> </div><div>and</div><div><br></div><div>B) gep 0, 0, 1, 1 -> points at the 4th i32 object</div><div><br></div><div>Unless I've missed the math somewhere, I think this works, and both gep 0, 1, 1 and gep 0, 0, 1 point at a struct.</div><div><br></div><div><br></div><div>In general, you can use an array element of the struct to do just about anything. And I can wrap any struct in an another struct, prefix it by an array, and then use that array to form GEPs that do crazy aliasing.</div></div></div></div>