-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Incorrect code generation for nalgebra's Matrix::swap_rows() #54462
Comments
LLVM upgrade as a cause was misidentified (for some reason early 1.29 nightly did report correct results at some point for me). The code works with There may still be UB somewhere in the code, but given our bad experience with |
Minimised test case with no unsafe code (make sure to compile with 1 codegen unit!):fn linidx(row: usize, col: usize) -> usize {
row * 1 + col * 3
}
fn swappy() -> [f32; 12] {
let mut mat = [1.0f32, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0];
for i in 0..2 {
for j in i+1..3 {
if mat[linidx(j, 3)] > mat[linidx(i, 3)] {
for k in 0..4 {
let (x, rest) = mat.split_at_mut(linidx(i, k) + 1);
let a = x.last_mut().unwrap();
let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();
::std::mem::swap(a, b);
}
}
}
}
mat
}
fn main() {
let mat = swappy();
assert_eq!([9.0, 5.0, 1.0, 10.0, 6.0, 2.0, 11.0, 7.0, 3.0, 12.0, 8.0, 4.0], mat);
} Output
To compile
setting |
cc @rust-lang/compiler this is probably a soundness issue. I’m not sure if it can be exploited to do bad things to memory, but I marked it as such to be safe. |
Discussed in T-compiler meeting. I will prepare a patch for at least master and beta changing the default to After that I’ll keep looking into the underlying issue to see if it can be easily fixed within LLVM. |
This will be re-enabled sooner or later depending on results of further investigation. Fixes rust-lang#54462
This will be re-enabled sooner or later depending on results of further investigation. Fixes rust-lang#54462
Do not put noalias annotations by default This will be re-enabled sooner or later depending on results of further investigation. Fixes #54462 Beta backport is: #54640 r? @nikomatsakis
This will be re-enabled sooner or later depending on results of further investigation. Fixes rust-lang#54462
The nalgebra linear algebra library has a swap_rows method which allows the user to swap two rows of a matrix. Unfortunately, I'm currently investigating a code generation heisenbug which causes this method to corrupt the matrix data in some circumstances.
Given the UB-like symptoms, and the fact that the implementation of swap_rows takes multiple (non-overlapping) &mut references to the target matrix, I wondered if this could be a violation of Rust's aliasing rules. However, @nagisa confirmed that this is not not the case, and that the compiler is probably the culprit here.
He identified the recent upgrade from LLVM 7 to LLVM 8 as a cause of this issue(but that later turned out to be incorrect).Here is a minimal reproducer of my problem:
To reproduce the issue, you must build in release mode. The issue is also sensitive to the amount of codegen units in flight, therefore I strongly recommend building with codegen-units=1 as well.
I expect the following output:
Instead, on my systems (nalgebra 0.16.2, rust 1.29, Ivy Bridge & Haswell CPUs) I get the following output:
The text was updated successfully, but these errors were encountered: