This is another attempt to handle situations similar to http://reviews.llvm.org/D8487 , although it won't work for that particular case (because this doesn't appear to be legal for arguments).
The basic idea is that given this code:
define void @struct() { %alloca = alloca %struct %alloca.i32 = bitcast %struct* %alloca to i32* %random = call i32* @random.i32(i32* %alloca.i32) %f0 = getelementptr inbounds %struct, %struct* %alloca, i32 0, i32 0 %p1 = getelementptr inbounds i32, i32* %random, i32 1 ret void }
%f0 and %p1 can not alias.
If they did alias, then the underlying object of %p1 - and thus, of %random - must be %alloca. But that would make %random out of bounds (since it'd have a negative offset) w.r.t %alloca, and since the GEP is inbounds, we can just assume noalias. The same logic probably holds for a GlobalVariable (which isn't a GlobalAlias), but not for other identified objects, like arguments, since a negative offset from a noalias argument may still be inbounds. I'd rather do this for Alloca first, and add GV in a separate commit.
The interface is pretty ugly, perhaps wrapping the results of DecomposeGEPExpression in a class and passing that around would make it better, but I'm not entirely sure. Thoughts?