It was more a jab at LLVM's documentation in general ;)
But since you're claiming to understand LLVM docs:
* How does LLVM identify that a region of memory is "allocated" per the usage in the GEP docs. In particular it may be useful to mark special addresses as "allocated" for special marker objects that don't actually exist.
* Does "in bounds" extend to arrays? e.g. can I offset even further from a ptr to foo if it's in an array of foo?
"Allocated" is something that arbitrary functions like "malloc" can define for themselves. LLVM specifies what can be done with "allocated memory", and then it's up to the API and implementation of malloc to provide something that works and is useful within LLVM's framework. Dereferencing "allocated" bytes through a proper pointer has to work. Dereferencing "unallocated" bytes is undefined behavior (regardless of whether the deference will succeed or fail in hardware).
LLVM's type system is mostly inert in its memory semantics. There is no difference between arrays or any other type of object with respect to what addresses can be computed and dereferenced. The important things are allocations which guarantee contiguous regions of memory.
That's also this tricky issue with C that's often ignored. If you have a nested array and take a pointer &foo[0][0], the only in bounds pointers are the pointers into the 0th subarray.
In general, LLVM semantics are largely derived from C and C++ in terms of undefined behavior (although some aspects, like signed overflow, are merely optional). The rule for "in bounds" means that pointers can only be manipulated to point to some address within the bounds of their object, or possibly the address just after the object (which cannot be dereferenced). A concrete example:
struct foo { int a; char b; int c[32]; } obj;
char ptr = &obj.b; char ptr2 = ptr + kerfuffle;
In this example, it is undefined behavior if kerfuffle is not in the range of [-sizeof(int), sizeof(obj) - sizeof(int)]. (e.g., ptr2 == &obj.c[32] is valid, but ptr2 == &obj.c[33] is not).