-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Recursion using extern "C"
causes miscompilation
#114312
Comments
extern "C"
caused miscompilationextern "C"
causes miscompilation
It seems, that bug was introduced between 1.69 and 1.70: |
I am not particularly well versed in miscompilations, but the IR we emit to LLVM looks fine. Investigating more later, but I suspect an LLVM update affects this. |
reduced LLVM IR: https://godbolt.org/z/Yncqrjfr7 define void @foo(ptr noalias byval(i64) %x) {
start:
%new_x = alloca i64, align 8
%x_val = load i64, ptr %x, align 8
%is_zero = icmp eq i64 %x_val, 0
br i1 %is_zero, label %end, label %recurse
recurse:
store i64 0, ptr %new_x, align 8
call void @foo(ptr %new_x)
br label %end
end:
ret void
} optimizes to define void @foo(ptr noalias nocapture readonly byval(i64) %x) {
%x_val = load i64, ptr %x, align 8
%is_zero = icmp eq i64 %x_val, 0
br i1 %is_zero, label %end, label %recurse
recurse:
br label %recurse
end:
ret void
} Needs Did not bisect, but this was probably introduced by the upgrade to LLVM 16: #109474 @rustbot label A-llvm I-unsound |
If anyone's interested in a Rust level test, it can be reduced a decent amount: #[repr(C)]
pub enum Expr {
Sum,
// must have more than usize data
Sub(usize, u8),
}
pub extern "C" fn eval_inner(expr: Expr) {
match expr {
Expr::Sum => {}
Expr::Sub(_, _) => eval_inner(Expr::Sum),
}
} looking at that LLVM IR it could probably be reduced more, but really at this point there's not a whole lot left to remove. |
Yeah, it looks like tailcallelim introducing a write to a Strangely, Alive2 is okay with writing to a This makes some sense semantically (since the hidden copy of the argument means modifications aren't visible to the caller), but seems to be in contradiction with the langref, which says:
Opened llvm/llvm-project#64289 |
Bisected: llvm/llvm-project@01859da. |
@rustbot claim |
@rustbot label +T-compiler +I-compiler-nominated Nominating for compiler discussion, because @DianQK is proposing the LLVM fix for backport to our 16 branch in rust-lang/llvm-project#150, in hopes of getting this into 1.72-beta. We don't really have a policy mechanism for this since master has already moved to LLVM 17, but we could accept that LLVM 16 backport in our fork and then update the LLVM 16 submodule directly in beta. (That would also pull in #114105.) |
I think this backport was necessary. It may have led to other undetected end-to-end miscompilation.
Something unexpected seems to have happened. Should we create a new rustc branch of llvm-project every time we create a beta branch? |
@rustbot label +regression-from-stable-to-stable |
It doesn't come up often, but we always have the option of adding a branch if needed. I think this particular case is innocuous enough to allow, but I didn't want it to sneak in without notice. |
Okay, I can reopen a new PR for the new branch if needed. |
Thanks for nominating @cuviper! We discussed this during the compiler triage meeting today and think that accepting a beta-backport of rust-lang/llvm-project#150 would be best to mitigate this miscompilation. We would prefer not to take #114105 at the same time and would rather let that ride the normal release train if that's possible? |
Since the master branch has been switched to LLVM 17. Possibly revert rust-lang/llvm-project#148 at branch rustc/16.0-2023-06-05 is also fine? |
In a way, that PR's backport got orphaned because its version of the submodule was derailed from the release train, replaced by our LLVM 17 update. But the original change it wanted is part of 17, so it will ride the train that way.
Yes, I think that sounds fine. Please go ahead and add that revert to rust-lang/llvm-project#150, noting these reasons in the revert commit message. When we apply the submodule update to beta, it should ideally come with a rust codegen test, and we'll also want that test to land on master when LLVM 17 is fixed. (And don't close this issue until then!) |
llvm/llvm-project-release-prs#556. |
[beta] Update LLVM to resolve a miscompilation found in 114312. Related issue: rust-lang#114312 . After the master updates the LLVM, we will add the same test cases. In the meantime, close the issue.
1.72-beta's LLVM 16 was fixed in #114726, so I'm moving the milestone to 1.73 until we update and test LLVM 17. |
I tried this code:
I expected to see this happen: compiled function correctly handles
Sub(x, y)
Instead, this happened: compiler generates code with infinite loop.
See asm (from
-Copt-level=3
):Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: