This is consistent with what is currently implemented in LLVM, as far as I know.
There's an alternative model where "dereferenceable" only applies at the point of the call/load. That might be more generally useful? But it doesn't match the implementation of Value::getPointerDereferenceableBytes.
DeadArgElim transforms
define void @f(i8* dereferenceable(16) %ptr) { ret void } define void @caller(i8* %v) { call void @f(i8* %v) ret void }to
define void @f(i8* dereferenceable(16) %ptr) { ret void } define void @caller(i8* %v) { call void @f(i8* undef) ret void }Given this semantic this transform is wrong, right?