Skip to content

SIGILL / LLVM ERROR from rustc when compiling to a x86_64 target that lacks SSE2 instructions #189

@japaric

Description

@japaric

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions