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

Compiling libcore without SSE leads to LLVM ERROR: SSE register return with SSE disabled #26449

Open
gz opened this Issue Jun 20, 2015 · 14 comments

Comments

Projects
None yet
9 participants
@gz

gz commented Jun 20, 2015

May be related to: #26025
At least compilation seems to work for June 17th nightly and earlier.

I tried this (creating libcore library without the use of vector instructions; this is typically done in case one wants to use libcore in kernel level code):

rustc-nightly/src/libcore $ rustc --crate-type=lib --emit=link -O -C soft-float -C target-feature=-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2 -g --emit=obj -C soft-float -C no-vectorize-slp -C no-vectorize-loops --crate-name core lib.rs 
LLVM ERROR: SSE register return with SSE disabled

I expected to see this happen: Successful compilation.

Instead, this happened: LLVM ERROR: SSE register return with SSE disabled

Meta

rustc --version --verbose:
rustc 1.2.0-nightly (2f56839 2015-06-18)
binary: rustc
commit-hash: 2f56839
commit-date: 2015-06-18
host: x86_64-unknown-linux-gnu
release: 1.2.0-nightly

@steveklabnik steveklabnik added the A-LLVM label Jun 23, 2015

@Roxxik

This comment has been minimized.

Show comment
Hide comment
@Roxxik

Roxxik Jun 29, 2015

I've investigated this a little further:
libcore cannot be compiled without mmx, sse and sse2
the following commands all fail

$ rustc -O -g --crate-type=lib --emit=link --emit=obj -C target-feature=-mmx --crate-name core lib.rs
LLVM ERROR: SSE register return with SSE disabled
$ rustc -O -g --crate-type=lib --emit=link --emit=obj -C target-feature=-sse --crate-name core lib.rs
LLVM ERROR: SSE register return with SSE disabled
$ rustc -O -g --crate-type=lib --emit=link --emit=obj -C target-feature=-sse2 --crate-name core lib.rs
LLVM ERROR: SSE2 register return with SSE2 disabled

the command above without those three disabled works for me

$ rustc --crate-type=lib --emit=link -O -C soft-float -C target-feature=-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2 -g --emit=obj -C soft-float -C no-vectorize-slp -C no-vectorize-loops --crate-name core lib.rs

I haven't tested whether the resulting object file is functional.

$ rustc --version --verbose

rustc 1.3.0-dev (40db46c 2015-06-29)
binary: rustc
commit-hash: 40db46c
commit-date: 2015-06-29
host: x86_64-unknown-linux-gnu
release: 1.3.0-dev

Roxxik commented Jun 29, 2015

I've investigated this a little further:
libcore cannot be compiled without mmx, sse and sse2
the following commands all fail

$ rustc -O -g --crate-type=lib --emit=link --emit=obj -C target-feature=-mmx --crate-name core lib.rs
LLVM ERROR: SSE register return with SSE disabled
$ rustc -O -g --crate-type=lib --emit=link --emit=obj -C target-feature=-sse --crate-name core lib.rs
LLVM ERROR: SSE register return with SSE disabled
$ rustc -O -g --crate-type=lib --emit=link --emit=obj -C target-feature=-sse2 --crate-name core lib.rs
LLVM ERROR: SSE2 register return with SSE2 disabled

the command above without those three disabled works for me

$ rustc --crate-type=lib --emit=link -O -C soft-float -C target-feature=-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2 -g --emit=obj -C soft-float -C no-vectorize-slp -C no-vectorize-loops --crate-name core lib.rs

I haven't tested whether the resulting object file is functional.

$ rustc --version --verbose

rustc 1.3.0-dev (40db46c 2015-06-29)
binary: rustc
commit-hash: 40db46c
commit-date: 2015-06-29
host: x86_64-unknown-linux-gnu
release: 1.3.0-dev

@eternaleye

This comment has been minimized.

Show comment
Hide comment
@eternaleye

eternaleye Jul 2, 2015

Contributor

To explain somewhat:

The x86_64 ABI states that it is mandatory for floating-point return values to be passed in SSE registers. On one level, this makes an enormous amount of sense: the 387 FPU being a weird 80-bit thing causes real issues, and every x86_64 CPU possesses SSE2.

On the other hand, LLVM doesn't offer any functionality along the lines of GCC's -mfpmath to override this behavior. At least at one point, adding +soft-float to the target fixed the issue, but I've heard that no longer does the trick.

Contributor

eternaleye commented Jul 2, 2015

To explain somewhat:

The x86_64 ABI states that it is mandatory for floating-point return values to be passed in SSE registers. On one level, this makes an enormous amount of sense: the 387 FPU being a weird 80-bit thing causes real issues, and every x86_64 CPU possesses SSE2.

On the other hand, LLVM doesn't offer any functionality along the lines of GCC's -mfpmath to override this behavior. At least at one point, adding +soft-float to the target fixed the issue, but I've heard that no longer does the trick.

@thepowersgang

This comment has been minimized.

Show comment
Hide comment
@thepowersgang

thepowersgang Jul 2, 2015

Contributor

And to state why one would want to disable SSE etc. When writing kernel-mode code, it is very undesirable to touch the floating-point or vector units, as they both require explicit initialization, and have very large register states that would have to be saved on all context switches.

Contributor

thepowersgang commented Jul 2, 2015

And to state why one would want to disable SSE etc. When writing kernel-mode code, it is very undesirable to touch the floating-point or vector units, as they both require explicit initialization, and have very large register states that would have to be saved on all context switches.

@eternaleye

This comment has been minimized.

Show comment
Hide comment
@eternaleye

eternaleye Jul 2, 2015

Contributor

Personally, I'd actually like the idea of splitting libcore into float-free and float-using parts, as there are embedded CPUs with no FPU that are also of interest.

Contributor

eternaleye commented Jul 2, 2015

Personally, I'd actually like the idea of splitting libcore into float-free and float-using parts, as there are embedded CPUs with no FPU that are also of interest.

@gz

This comment has been minimized.

Show comment
Hide comment
@gz

gz Jul 2, 2015

Just adding a feature to disable floating point related functions/types etc. should be sufficient for architectures that do not support it or codebases that do not want to use it, right?

gz commented Jul 2, 2015

Just adding a feature to disable floating point related functions/types etc. should be sufficient for architectures that do not support it or codebases that do not want to use it, right?

@thepowersgang

This comment has been minimized.

Show comment
Hide comment
@thepowersgang

thepowersgang Jul 2, 2015

Contributor

@gz Adding a cfg() flag that disables compilation of the floating-point functions did allow libcore to be compiled with SSE etc disabled. See https://github.com/thepowersgang/rust_os/blob/master/libcore_nofp.patch for a patch on for the latest nightly.

I'm not sure what the best long-run solution would be, but probably having a #[cfg] flag is best (and making sure it gets tested correctly).

As a related note - Could that LLVM error message be changed to include the offending function? (I'm not sure where such a change would happen, in the rust branch, or in upstream LLVM)

Contributor

thepowersgang commented Jul 2, 2015

@gz Adding a cfg() flag that disables compilation of the floating-point functions did allow libcore to be compiled with SSE etc disabled. See https://github.com/thepowersgang/rust_os/blob/master/libcore_nofp.patch for a patch on for the latest nightly.

I'm not sure what the best long-run solution would be, but probably having a #[cfg] flag is best (and making sure it gets tested correctly).

As a related note - Could that LLVM error message be changed to include the offending function? (I'm not sure where such a change would happen, in the rust branch, or in upstream LLVM)

gz added a commit to gz/rust that referenced this issue Jul 3, 2015

Add disable_float cfg target for #26449.
This allows to compile libcore on architectures that lack floating point support
or to use libcore in kernel code without worrying about saving and restoring
the floating point register state inside the kernel.

gz added a commit to gz/rust that referenced this issue Jul 3, 2015

gz added a commit to gz/rust that referenced this issue Jul 3, 2015

@gz

This comment has been minimized.

Show comment
Hide comment
@gz

gz Jul 4, 2015

FYI I submitted a pull request for this: #26749

gz commented Jul 4, 2015

FYI I submitted a pull request for this: #26749

@gz

This comment has been minimized.

Show comment
Hide comment

gz commented Aug 8, 2015

@Zoxc

This comment has been minimized.

Show comment
Hide comment
@Zoxc

Zoxc Oct 30, 2015

Contributor

If you build libcore with floating point support and link to it using -C lto you will only get LLVM errors if you actually use some floating point functionality in libcore. That is how I use it in my kernel.

@gz I don't think building libcore without floating point has ever worked. Do you happen to know a version where this works?

Contributor

Zoxc commented Oct 30, 2015

If you build libcore with floating point support and link to it using -C lto you will only get LLVM errors if you actually use some floating point functionality in libcore. That is how I use it in my kernel.

@gz I don't think building libcore without floating point has ever worked. Do you happen to know a version where this works?

@emk

This comment has been minimized.

Show comment
Hide comment
@emk

emk Oct 30, 2015

Contributor

I'm also getting bitten by this one, for much the same reasons that the powersgang mentions above. I'm starting from Philipp Oppermann's series of blog posts on writing an OS in Rust, and trying to add interrupt support. Unfortunately, saving the floating point registers on every interrupt slows everything down and requires much more fiddling around, which is why most x86 kernels avoid floating point. And of course, there are plenty of other processors without floating point out there.

For this kind of bare-metal use, it would be very nice to have some way of convincing Rust to stop emitting floating point instructions and still manage to build core.

Contributor

emk commented Oct 30, 2015

I'm also getting bitten by this one, for much the same reasons that the powersgang mentions above. I'm starting from Philipp Oppermann's series of blog posts on writing an OS in Rust, and trying to add interrupt support. Unfortunately, saving the floating point registers on every interrupt slows everything down and requires much more fiddling around, which is why most x86 kernels avoid floating point. And of course, there are plenty of other processors without floating point out there.

For this kind of bare-metal use, it would be very nice to have some way of convincing Rust to stop emitting floating point instructions and still manage to build core.

@thepowersgang

This comment has been minimized.

Show comment
Hide comment
@thepowersgang

thepowersgang Oct 30, 2015

Contributor

At the moment - the best way is to patch libcore locally before compiling, I'm still maintaining the patchset that does that for my kernel project.

Contributor

thepowersgang commented Oct 30, 2015

At the moment - the best way is to patch libcore locally before compiling, I'm still maintaining the patchset that does that for my kernel project.

@emk

This comment has been minimized.

Show comment
Hide comment
@emk

emk Oct 30, 2015

Contributor

@thepowersgang: Thank you for the suggestion! For anybody else running into this problem, I found a copy of disable_float libcore_nofp patch in @thepowersgang's OS repository. It's surprisingly small.

Looking at your patch, it looks very straightforward and "principled", if you will: It specifically excludes everything in libcore related to floating point without any gross hackery. It just disables f32, f64, and the related APIs.

Contributor

emk commented Oct 30, 2015

@thepowersgang: Thank you for the suggestion! For anybody else running into this problem, I found a copy of disable_float libcore_nofp patch in @thepowersgang's OS repository. It's surprisingly small.

Looking at your patch, it looks very straightforward and "principled", if you will: It specifically excludes everything in libcore related to floating point without any gross hackery. It just disables f32, f64, and the related APIs.

@gz

This comment has been minimized.

Show comment
Hide comment
@gz

gz Oct 31, 2015

@Zoxc: Yes, it worked before #26025 (see bug description)

gz commented Oct 31, 2015

@Zoxc: Yes, it worked before #26025 (see bug description)

@parched

This comment has been minimized.

Show comment
Hide comment
@parched

parched Jul 21, 2016

Contributor

@gz You need to add the +soft-float target feature

Contributor

parched commented Jul 21, 2016

@gz You need to add the +soft-float target feature

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment