-
Notifications
You must be signed in to change notification settings - Fork 78
Fix load alignment being applied to referenced value #551
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
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: