-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How do aliasing model protectors interact with tail calls? #523
Comments
Assuming that ...Well, grepping the LLVM source for musttail, there are more references than I thought, mostly in order to avoid breaking the musttail invariants in various passes… But it doesn't seem to affect aliasing. Here is an example program demonstrating the need for protectors. Since rustc doesn’t seem to be able to generate LLVM IR for |
@comex so in that example, Something is odd about this though, the implicit reborrow of |
Okay the other UB doesn't happen because of a surprising two-phase borrows interaction. So getting back to @comex's example: |
Heh. I had no idea that two-phase borrows were involved; I was just fiddling with the code until the version with |
FWIW here is a variant that does not rely on two-phase borrows. #![allow(incomplete_features)]
#![feature(explicit_tail_calls)]
use std::cell::UnsafeCell;
fn test2(x: *mut i32, y: *mut i32, loop_count: i32) -> i32 {
unsafe {
let mut val = 0;
for _ in 0..=loop_count {
// This load gets moved down:
val = *x;
// Conflicting store:
*y = 200;
}
val
}
}
#[inline(never)]
#[no_mangle]
fn test1(x: &mut i32, y: *mut i32, loop_count: i32) -> i32 {
// Optionally comment out `become` here.
become test2(x as *mut i32, y, loop_count)
}
fn main() {
let x = &mut 100;
let y = x as *mut _;
let ret = test1(unsafe { &mut *y }, y, 0);
assert_eq!(ret, 100);
} |
In code like this
x
is protected insidetest1
. Is it also still protected whiletest2
runs?If we want
become
to behave mostly likereturn
, the answer should be "yes". However,test1
's stack frame is guaranteed to not exist any more whentest2
runs, so maybe it would make sense to say that the protectors associated with that stack frame have also expired?The answer may be decided for us by LLVM, depending on what they say about the scope of
noalias
anddereferenceable
in a function with a tail call: is the tail call inside or outside the scope ofnoalias
anddereferenceable
of a function argument?The text was updated successfully, but these errors were encountered: