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.
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:
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.