-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Bug on non-power-of-2 SIMD vectors #20460
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
Comments
As you can see, this is a fault of |
Ack! |
CC @thestinger |
I've got through some little experiment and I guess there's something wrong with
I think now we've got 2 available options.
I'm pretty new with Rust. Someone pleaes make me an advise! |
I'm not sure what the exact behaviour should be. Part of the problem is that non-power-of-two SIMD types don't exist on most platforms, so it gets widened to whatever it needs to be. However, an f32x3 is still only 12 bytes of actual data. I think that Vec should handle the case anyway. Whether the case should come up... I don't really know. |
Given that sizeof (f32x3, u32) == 32, it seems like rust already adds padding for SIMD types, so it's simply size_of that's broken, and should include the padding. At the same time, Vec should probably assert that size_of T >= min_align_of T to catch any errors if in the future there are any types where their size is less than their alignment. |
Nominating because the required change may be a back-compat change to some primitive semantics. |
Actually, thinking about it some more. I believe that the current behaviour is correct. The whole point of having a different alignment to size is to cover these kinds of cases, where the number of usable bytes is not a nice integer multiple of the alignment. |
@Aatch In that situation, the extra padding is added to meet the alignment requirements of "u64", not the "i8". In the SIMD example, the extra padding is part of the SIMD type. Either the compiler should not add any padding and sizeof (f32x3, u32) == 16, and any accesses take care to preserve the u32 or as is more usual, the SIMD type should include it's padding. edit: |
Amusingly, The issue is caused by size_of being implemented as a call to this function: rust/src/librustc_trans/trans/machine.rs Line 52 in 618bd5d
The comment above the function is wrong: LLVM does include padding when calculating the size of types, but only for structs (not for vectorised types), which makes that function fairly useless and definitely not the preferred option as the comment suggests. |
NB. |
Current size_of::<T>() = ceil(LLVMSizeOfTypeInBits() / 8)
min_align_of::<T>() = LLVMABIAlignmentOfType() and I found that current LLVM doesn't have any guarantee between For example, Now I see 2 options here
References
|
@huonw I meant more-so the size_of semantics, but simd semantics might also be affected. |
I think this is a compiler bug. There are many low-level APIs assuming that size is a multiple of the alignment... |
For example, C11's |
Unfortunately, forcing |
@greeter |
Currently I'm testing e4c20db, and it seems to cause no trouble. Please make me an advise if I'm doing something wrong. |
OK Let's do this → #20611 |
This PR fixes the issue rust-lang#20460, and it doesn't touch any existing behavior except the bug of the SIMD types. Closes rust-lang#20460.
I think I found a bug with non-power-of-2 SIMD vectors. They're randomly turned into zero values when I store them on
Vec
http://is.gd/LfOHbj
Expected result:
What we get:
Tested with:
The text was updated successfully, but these errors were encountered: