For recursive phis, we skip the recursive operands and check that the remaining operands are NoAlias with an unknown size. Currently, this is limited to inbounds GEPs with positive offsets, to guarantee that the recursion only ever increases the pointer.
Make this more general by only requiring that the underlying object of the phi operand is the phi itself, i.e. it it based on itself in some way. To compensate, we need to use a beforeOrAfterPointer() location size, as we no longer have the guarantee that the pointer is strictly increasing.
This allows us to handle some additional cases like negative geps, geps with dynamic offsets or geps that aren't inbounds.