RustCrypto / RustCrypto/universal-hashes
SIGILL / LLVM ERROR from rustc when compiling to a x86_64 target that lacks SSE2 instructions
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 39
- Forks
- 23
- Avg merge
- 1h 57m
- Merged PRs (30d)
- 2
Description
Steps to reproduce
$ cargo new --lib repro
$ cd repro
$ echo '#![no_std]' > src/lib.rs
$ cargo add poly1305@0.8.0
$ rustup default 1.73.0
$ rustup target add x86_64-unknown-none
$ cargo b --target x86_64-unknown-none
error: could not compile `poly1305` (lib)
Caused by:
process didn't exit successfully: `$RUSTUP_TOOLCHAIN/bin/rustc (..)` (signal: 4, SIGILL: illegal instruction)
at some point I was able to get a "LLVM ERROR" message but I can't no longer reproduce that
after some digging it seems that the lack of SSE2 instructions in the x86_64-unknown-none is the problem:
$ rustup default nightly-2023-11-15
$ rustc -Z unstable-options --print target-spec-json --target x86_64-unknown-none | grep features
"features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float",
creating a custom target that adds back the sse2 feature makes the crate compile
$ rustc -Z unstable-options --print target-spec-json --target x86_64-unknown-none > x86_64.json
patch the JSON like this
--- before.json 2023-11-15 14:35:19.565448966 +0100
+++ x86_64.json 2023-11-15 14:35:10.115355396 +0100
@@ -5,8 +5,7 @@
"crt-objects-fallback": "false",
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"disable-redzone": true,
- "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float",
- "is-builtin": true,
+ "features": "-mmx,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2",
"linker": "rust-lld",
"linker-flavor": "gnu-lld",
"llvm-target": "x86_64-unknown-none-elf",
$ rustup component add rust-src
$ cargo b -j1 -Z build-std=core --target ./x86_64.json && echo OK
OK
keeping the -sse2 produces "LLVM ERROR: Access past stack top!"
perhaps the auto_detect module could use #[cfg(not(target_feature = "sse2"))] to skip the auto-detection and directly use the soft implementation? or you could add something like this:
#[cfg(not(target_feature = "sse2"))]
compile_error!("compilation targets without SSE2 instructions are not supported");
which is nicer than the SIGILL
for additional context ("why are you even using this target?"): I was looking for a built-in "OS agnostic" / no-std target for a no-std rustls demo (rustls/rustls PR1534) and tried x86_64-unknown-none and run into this and other problems. I ended up using a custom target for the demo but I figured I should still report what I found.
by the way, the sha2 has a similar problem with this target. Let me know if you think I should report a similar issue in the hashes repo.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the failure with poly1305 0.8.0 on rustc 1.73.0 using the x86_64-unknown-none target and inspect the target features shown by rustc. Start with the auto_detect module and the existing soft implementation. Done should be a clear, tested behavior for targets without SSE2, whether that is selecting the soft implementation or reporting that the target is unsupported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- build-system, cryptography
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100