Clarifying pointer aliasing rules


There seems to be an inconsistency between the GEP documentation and
the pointer aliasing rule:

"A pointer value formed by an inttoptr is based on all pointer values
that contribute
(directly or indirectly) to the computation of the pointer’s value."

My interpretation of this wording is that a pointer value is based on
a set of possible objects.
This has the (unintended?) consequence of allowing "inter-object" GEP
whose resulting addresses can be used to access multiple objects.
I am not sure if this interpretation of this clause is what is intended by both
the community and what is currently implemented in code.

Here's an example in psuedo IR to demonstrate this point (assume all
pointers are i8*):

p = alloca
q = alloca
p_int = ptrtoint p
q_int = ptrtoint q
p_or_q_int = select ( p < q ) p q
pq_diff = select ( p < q ) ( q - p ) ( p - q )
p_or_q = inttoptr p_or_q_int
x = gep p_or_q pq_diff
load x

Due to a control dependency, both "p" and "q" contribute to the
computation of "p_or_q_int".
Thus, in the old wording, "p_or_q" is based on both objects.
"p_or_q" is an address within either "p" or "q",
GEP (non-inbounds) then computes an address that "jumps" to the other object,
and since the computed value is based on both objects, it can be dereferenced.
This contradicts the wording in GetElementPtr.html:
"It’s invalid to take a GEP from one object, address into a different
separately allocated object, and dereference it."

Is my interpretation correct?