Closed
Description
There are programs that are accepted by Stacked Borrows and conflict with LLVM noalias. @arielb1 had the following example in this long discussion on Zulip:
let x: &mut u32 = a;
let raw_ptr: *const u32 = x;
foo(x, raw_ptr);
fn foo(x: &mut u32, raw_ptr: *const u32) -> u32 {
let x = &mut *x; // stack is now [..., Uniq(N)]
*x = 5;
let y = &*x; // stack is now [..., Uniq(N), Shr]
// this is OK according to stacked borrows because of the Shr tag, but is UB
// according to LLVM noalias and would be hard to make non-UB.
unsafe { *raw_ptr }
}
On a high level, the problem is that create a raw reference is like a "broadcast" that lets every raw pointer now access this location, whereas LLVM only lets newly created raw pointers be used for that.