Currently LLVM is relying on ValueTracking's isKnownNonZero to attach nonnull, which can return true when the value is poison.
To make the semantics of nonnull consistent with the behavior of isKnownNonZero, this makes the semantics of nonnull to accept poison, and return poison if the input pointer isn't null.
This makes many transformations like below legal:
%p = gep inbounds %x, 1 ; % p is non-null pointer or poison call void @f(%p) ; instcombine converts this to call void @f(nonnull %p)
This semantics makes propagation of nonnull to caller illegal.
The reason is that, passing poison to nonnull does not immediately raise UB anymore, so such program is still well defined, if the callee does not use the argument.
Having noundef attribute there re-allows this.
define void @f(i8* %p) { ; functionattr cannot mark %p nonnull here anymore call void @g(i8* nonnull %p) ; .. because @g never raises UB if it never uses %p. ret void }
Another attribute that needs to be updated is align. This patch updates the semantics of align to accept poison as well.
poison is not aligned, and can well be null. Let's state the intent and not "include" poison as valid input. It is not and that is why it triggers the output to be poison.