If a pointer is marked as dereferenceable_or_null(N), LLVM assumes it
is either null or dereferenceable(N) or both. This change only
introduces the attribute and adds a token test case for the llvm-as
/ llvm-dis. It does not hook up other parts of the optimizer to
actually exploit the attribute -- those changes will come later.
For pointers in address space 0, dereferenceable(N) is now exactly
equivalent to dereferenceable_or_null(N) && nonnull. For other
address spaces, dereferenceable(N) is potentially weaker than
dereferenceable_or_null(N) && nonnull (since we could have a null
dereferenceable(N) pointer).
The motivating case for this change is Java (and other managed
languages), where pointers are either null or dereferenceable up to
some usually known-at-compile-time constant offset.
Please explicitly note that it can only be both when not in addrspace(0). When not in addrspace(0), does this attribute imply that null is not dereferenceable (even if it would be otherwise)?
On the other hand, if dereferenceable_or_null(n) is equivalent to dereferenceable(n) for non-addrspace(0) pointers, maybe we should disallow it to avoid confusion.