- Notifications
You must be signed in to change notification settings - Fork 137
fix: 32 bits architecture crash #104
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
Conversation
When using imagequant on 32 bit env I had this bug: crossbeam expects pointers (data) to be aligned on 16 bits (because of this repr(C, align(16)))
| I don't understand the issue. The alignment is in bytes. It applies to a struct that contains 32-bit/4-byte floats, which usually get 4-byte alignment. I override it to be aligned to 16 bytes. Every 16-byte-aligned pointer is also a valid 4-byte-aligned pointer. |
| You are right in what you said, although it's not the problem. The problem is that I can have 8byte aligned pointers on 32bits arch (0xABC8), although, crossbeam and probably every So my pointer 0xABC8 cannot I know what you are doing with the |
| I indeed in my first message, mixed up bits & bytes, I hope that my new explanation is better |
| I understand the change you're proposing, but I don't understand reasoning behind it. I still don't follow how is crossbeam related? Do you have a demo code that demonstrates the problem? How do you get the misaligned pointer? How come alignment of an internal data type affects anything for you? I also don't see why any Rust code would ignore alignment of a data type declared in Rust. I should be able to put For example, in Rust it's invalid to cast |
| I will make a demo, but on 32 bits (wasm) I managed to do it It's crossbeam related in that it's where the error appears, in a Now that you say it, it's possible that it's a Rust error but I doubt it |
| In debug: align_of::<T>() = 16 ptr as usize % align_of::<T>() = 8Stack trace: |
| https://github.com/erwanvivien/gifski/tree/wasm-test To reproduce: change Cargo.toml imagequant to use real imagequant imagequant = "4.1"then |
| Any update on this PR? I think this PR is very non-destructive and should be considered :) |
| I haven't had time to check this yet — that repo is far from being a minimal reproducer, and has tons of other code, WASM threads, polyfills, hacks, etc. I do not want to make a change that doesn't seem to make sense. I don't see a logical reason why this alignment in this library would be wrong. It works correctly on 32-bit x86, as well as on a few other platforms. If there is a struct with a large alignment, it's simply not legal for a pointer to exist to this strut with smaller alignment. When the pointer isn't aligned properly, that's not the fault of the struct, that's a bug in code that created this pointer. So you're not dealing here with an issue in libimagequant. It more looks like a bug in the environment using the library, which could be a bug in the WASM compiler or WASM runtime. |
| I haven't got time to set it up in wasm, so I'll just merge it as is. |
| Thanks Kornelski, a side note: I tried to write the code for Wasm SIMD (in My simple benchmark showed from 33s (no SIMD) to 39s (with SIMD), and the need to recompile with specific flags to enable them, so it's not worth I think |
#[cfg(target_arch = "wasm32")] #[inline(always)] pub fn diff(&self, other: &f_pixel) -> f32 { unsafe { use std::arch::wasm32; let px = wasm32::f32x4(self.0.a, self.0.r, self.0.g, self.0.b); let py = wasm32::f32x4(other.0.a, other.0.r, other.0.g, other.0.b); // y.a - x.a let alphas = wasm32::f32x4_splat(other.0.a - self.0.a); let onblack = wasm32::f32x4_sub(px, py); // x - y let onwhite = wasm32::f32x4_add(onblack, alphas); // x - y + (y.a - x.a) let onblack = wasm32::f32x4_mul(onblack, onblack); let onwhite = wasm32::f32x4_mul(onwhite, onwhite); let max = wasm32::f32x4_max(onwhite, onblack); let mut max_store = [0f32; 4]; wasm32::v128_store(max_store.as_mut_ptr() as *mut _, max); // add rgb, not a max_store[1] + max_store[2] + max_store[3] } }Here's the whole patch: wasm32-simd.patch |
When using imagequant on 32 bit env I had this bug:
crossbeam expects pointers (data) to be aligned on 16 bits (because of this repr(C, align(16))) but on 32 bits arch, we can have pointers (data) aligned on 8 bits