-
Notifications
You must be signed in to change notification settings - Fork 60
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
Fix load alignment being applied to referenced value #551
base: master
Are you sure you want to change the base?
Conversation
The load alignment is somewhat confusing.
Could you please share an example where this happens? |
I'll try to make an example tomorrow. |
ok I think I've got it now. Also, I have some code to reproduce the problem. // repr(C) to prevent any field reordering.
#[repr(C)]
struct X {
// This causes the struct to require 8 byte alignment.
a: u64,
// This field is aligned to 8 bytes because the struct is aligned to 8 bytes, and it's at offset 8.
// The type itself only requires 4 bytes, though.
b: u32,
c: u32,
d: u32,
}
#[inline(never)]
fn foo(b1: u32, b2: u32) {
dbg!(b1);
dbg!(b2);
}
#[inline(never)]
fn bar(x: &X) {
// x.b loads the value from b with 8-byte alignment.
// The load result also has 8-byte alignment, so when being passed to foo,
// the second argument gets aligned to 8-bytes and is passed at argument offset 8
// as if it were the third 4-byte argument.
foo(x.b, x.b);
}
fn main() {
let x = X {
a: 1,
b: 2,
c: 3,
d: 4,
};
bar(&x);
} So I think maybe the alignment shouldn't be applied to the load result. |
Can you explain what's the expected result with this code? I get:
which seems good. |
I'm getting 2 on the first line and some random value on the second. |
Which architecture are you on? |
I was trying mips-unknown-linux-gnu. Also, it only happens with |
Do you know if it would be easy to add a test for this fix? |
I think a test for the behavior might not be perfectly reliable because the bug could accidentally be optimized out, but I'll try. I think maybe with a higher field alignment it'll happen on m68k, too. |
Did you want to add a test or would you want to merge this as is? |
I'd like to try to add a test that works on the architectures currently being tested in CI. |
Ok, please tell me when it's ready! |
In some code I compiled, the
align
argument (edit: inBuilder::load
) wasn't the same as the pointer's regular alignment, and gcc ended up dereferencing the wrong address. So I think thealign
argument is meant to only apply to the loaded value and not to the one that's being read.For comparison, rustc_codegen_llvm does the following: