GVN: Only propagate borrows from SSA locals
Fixes https://github.com/rust-lang/rust/issues/141313. This is a more principled fix than https://github.com/rust-lang/rust/pull/147886.
Using a reference that is not a borrowing of an SSA local at a new location may be UB.
The PR has two major changes.
The first one, when introducing a new dereference at a new location, is that the reference must point to an SSA local or be an immutable argument. `dereference_address` has handled SSA locals.
The second one, if we cannot guard to the reference point to an SSA local in `visit_assign`, we have to rewrite the value to opaque. This avoids unifying the following dereferences that also are references:
```rust
let b: &T = *a;
// ... `a` is allowed to be modified. `c` and `b` have different borrowing lifetime.
// Unifying them will extend the lifetime of `b`.
let c: &T = *a;
```
See also https://github.com/rust-lang/rust/issues/130853.
This still allows unifying non-reference dereferences:
```rust
let a: &T = ...;
let b: T = *a;
// ... a is NOT allowed to be modified.
let c: T = *a;
```
r? @cjgillot