-
Notifications
You must be signed in to change notification settings - Fork 28
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 build for targets that don't support sse2
, sse4.2
, or pclmulqdq
features
#22
Conversation
…mulqdq` features
Hi, thanks for the report and fix! FWIW, the actual instruction calls are guarded via I'm a bit reluctant to directly merge this in, because that seems like it would result in the fast paths only enabled when the build target is explicitly specified to support the instruction sets for the fast path, which may not the default case for all of them (e.g. Can you share a little more about the environment you're seeing the error in, so I could try to reproduce and potentially toy around with a few options? For example from the
|
Agreed, I'm not sure how I got those runtime errors originally (probably by changing the target but not the OS bootstrap behavior), but the LLVM build-time failure is reproducible.
Understood, and I wouldn't want to jeopardize existing usage by other targets. Another option would be to modify the build.rs script to consider the available target features.
Yes, that may be correct, but I wanted to be absolutely certain that all required features were supported by the actual target before using them. I can experiment with various combinations of those 3 feature flags to see whether sse2 encompasses the others sufficiently.
Certainly! I'm building this for Theseus OS, which uses a fairly normal x86_64 compiler target that disables SIMD in favor of soft floating point. This is a common approach in kernels to avoid needing to save all SIMD registers on every context switch. The target spec file can be found here, note which features are disabled. The log I get when building this crate for that target: $ cargo build --no-default-features -Z unstable-options -Z build-std=core,alloc -Z build-std-features=compiler-builtins-mem --target x86_64-theseus.json
Compiling crc32fast v1.2.1 (/home/kevin/crc32fast)
LLVM ERROR: Do not know how to split the result of this operator!
error: could not compile `crc32fast` If that's not enough details to reproduce it, I could create a separate repo that demonstrates the problem too. Just let me know, thanks! |
Digging deeper into the code, the culprit is that the calculate function is unconditionally instructed to use & emit SIMD instructions by means of the There are a few ways to fix this.
|
Hey, so I'm pretty sure that the runtime-guarding itself is okay; we will only ever return the specialized struct from the constructor if the runtime architecture meets all of our requirements, and the Having played around with a few different combinations of
Would that work for you? |
I agree, the runtime checking appears to be correct.
I'll test this out and let you know if it still builds correctly. Thanks for proposing a new/better fix! |
Good news, I can confirm that change works for all of my build targets, including soft float, sse, avx, and more. Thanks for digging into this with me and helping me arrive at the correct fix! I've pushed a commit that gates the specialized module behind only the |
Out of curiosity, were you able to reproduce that LLVM build error? |
Awesome, thanks so much! I'll merge this in now, and then cut a release later today.
Yep, was able to reproduce using your target file, thanks again for supplying that! |
Great! Glad to hear it, thanks again. |
Published as version |
The current
build.rs
script emits thecrc32fast_stdarchx86
cfg if the version of rustc is greater than 1.27, regardless of the underlying compilation target.However, when building this crate for targets that don't support the
sse2
,sse4.2
, andpclmulqdq
features, the compiler will still emit SSE instructions. This causes one of two very strange problems:LLVM ERROR: Do not know how to split this operator's operand!
, which (I think) occurs because LLVM is not expecting to parse/emit SSE instructions when not configured to do so.This PR adds the correct feature gates to ensure that invalid instructions cannot be emitted, i.e., that SSE instructions are only used if the target machine supports them.
Related: the
memchr
crate already experienced this problem. Some related issues: