[IR] Enable dereferenceable-at-point semantics (#204795)
The precise semantics of `dereferenceable` are currently undocumented,
but de facto they are:
* Argument position `dereferenceable` implies that the memory remains
dereferenceable while the function executes.
* Return position `dereferenceable` implies that the memory remains
dereferenceable forever.
This is not coherent with how these attributes are used, in at least two
ways:
* C++ reference arguments are annotated as `dereferenceable` by Clang.
However, C++ does not actually make any guarantees that the underlying
memory does not get freed during the execution of the function. (Unlike
Rust, which does guarantee this via protectors in SB/TB.)
* We infer `dereferenceable` on allocator return values (from
`allocsize`). Allocator return values quite obviously do not stay
dereferenceable forever, as they can be freed.
This PR changes the semantics of `dereferenceable` to apply at-point,
i.e. only directly on function entry (for arguments), or at the position
of the call (for return values). The fact that the memory cannot be
freed between the point where the `dereferenceable` fact has been
established and the point where we're trying to speculate needs to be
explicitly proven now.
The main ways this happens is:
* Via `nofree` function attributes (inferred).
* Via `noalias nofree` argument attributes. The latter is inferred, but
the former generally requires frontend annotation. In Rust the
combination of `noalias nofree dereferenceable` is used, so it should
not be materially affected by these changes.
* Context-sensitive analysis to check for frees (i.e. non-nofree calls
or synchronizing atomics) between the point of definition and the point
of speculation.
It's expected that this will regress optimization of C++ code in some
cases, because we can no longer use dereferenceability facts that are
not, in fact, guaranteed to hold.
This finishes implementing an old RFC:
https://discourse.llvm.org/t/rfc-decomposing-deref-n-into-deref-n-nofree/57873
GitOrigin-RevId: 5969d640a349d593b5935fbe80be89f7a375f528
1 file changed