Skip to content

x86_64 with SSE2 disabled: Assertion failed: (Reg >= X86::FP0 && Reg <= X86::FP6 && "Expected FP register!"), function getFPReg #29774

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

Open
DimitryAndric opened this issue Sep 17, 2016 · 23 comments
Labels
backend:X86 bugzilla Issues migrated from bugzilla confirmed Verified by a second party crash-on-invalid metabug Issue to collect references to a group of similar or related issues.

Comments

@DimitryAndric
Copy link
Collaborator

Bugzilla Link 30426
Version trunk
OS All
CC @dyung,@emaste,@francisvm,@RKSimon,@phoebewang,@rnk,@rotateright,@tstellar,@yurivict

Extended Description

This is a rather strange one. I got a test case via FreeBSD bug 212703 [1], where somebody encountered a clang 3.4.1 segfault, compiling some sample from openMVG [2].

This segfault is actually the assertion "(Reg >= X86::FP0 && Reg <= X86::FP6 && "Expected FP register!"), function getFPReg", and it even reproduces with trunk r281149.

For some reason, the build process targets x86_64, but then turns off SSE2, and this is the key to getting the assertion. The test case is extremely minimal, and optimization isn't even required:

// compile with: clang -cc1 -triple x86_64 -S -target-feature -sse2 testcase.cpp
void fn1(double);
int main() { fn1(4.); }

As far as I know, disabling SSE2 also disables all the higher forms of SSE, so I think it just can't find any x87 FP register at all, in this case?

[1] https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=212703
[2] https://github.com/openMVG/openMVG

@RKSimon
Copy link
Collaborator

RKSimon commented Sep 17, 2016

Duplicate of [Bug #​10498]?

@llvmbot
Copy link
Member

llvmbot commented Sep 18, 2016

Is x86-64 without sse2 a configuration we try to support?
As far as I know, x86-64 implies sse2 (and the x86-64 System V ABI certainly does).

@DimitryAndric
Copy link
Collaborator Author

Is x86-64 without sse2 a configuration we try to support?

Maybe not, though it would be better to simply refuse the -mno-sse and -mno-sse2 options on the command line then.

As far as I know, x86-64 implies sse2 (and the x86-64 System V ABI certainly
does).

Could it just fall back to x87 floating point? Maybe that was the expectation in openMVG... Though reading its CMake files, it appears that it may simply fail to detect SSE2 properly, and then tries to disable it.

@DimitryAndric
Copy link
Collaborator Author

Duplicate of [Bug #​10498]?

Yeah, it looks quite a bit like it; maybe the call to fn1() uses SSE registers, while the function itself expects x87 FP registers, or something like that.

@llvmbot
Copy link
Member

llvmbot commented Sep 18, 2016

Is x86-64 without sse2 a configuration we try to support?

Maybe not, though it would be better to simply refuse the -mno-sse and
-mno-sse2 options on the command line then.

That's what I meant.

As far as I know, x86-64 implies sse2 (and the x86-64 System V ABI certainly
does).

Could it just fall back to x87 floating point?

Not really. It could for computation, but not for the ABI - if the calling convention mandates returning in xmm0, there's no real fallback that makes sense.

GCC appears to actually make this distinction, so it will only refuse to compile when it sees an actual ABI problem. So, say:

float square(float f) {
return f * f;
}

When built with GCC for x86-64 with -mno-sse, errors with: "SSE register return with SSE disabled". GCC is, however, perfectly willing to compile it with only SSE2 disabled.

@rnk
Copy link
Collaborator

rnk commented Sep 22, 2016

Is x86-64 without sse2 a configuration we try to support?

Maybe not, though it would be better to simply refuse the -mno-sse and
-mno-sse2 options on the command line then.

That's what I meant.

Let's do that. Users seem to keep bumping into impossibilities in x86_64 -mno-sse[2], and then clang asks them to file a bug report.

@francisvm
Copy link
Collaborator

Maybe this can help: https://reviews.llvm.org/D27522.

@rnk
Copy link
Collaborator

rnk commented May 12, 2017

Maybe this can help: https://reviews.llvm.org/D27522.

I landed a modified version of this patch. However, it's still possible to hit this assertion, so the issue is not fixed.

@DimitryAndric
Copy link
Collaborator Author

Maybe this can help: https://reviews.llvm.org/D27522.

I landed a modified version of this patch. However, it's still possible to
hit this assertion, so the issue is not fixed.

Reid, any ideas what kind of situation can still trigger that?

@rnk
Copy link
Collaborator

rnk commented May 18, 2017

Maybe this can help: https://reviews.llvm.org/D27522.

I landed a modified version of this patch. However, it's still possible to
hit this assertion, so the issue is not fixed.

Reid, any ideas what kind of situation can still trigger that?

This test case was part of r302835, the revision that I forgot to note:

+void take_double(double);
+void pass_double(void) {

  • // FIXME: Still asserts.
  • //take_double(1.5);
    +}

@tstellar
Copy link
Collaborator

Maybe this can help: https://reviews.llvm.org/D27522.

I landed a modified version of this patch. However, it's still possible to
hit this assertion, so the issue is not fixed.

Reid, any ideas what kind of situation can still trigger that?

The test case attached to #10870 still hits this assertion with trunk (r353878).

@DimitryAndric
Copy link
Collaborator Author

DimitryAndric commented May 23, 2020

*** Bug #36415 has been marked as a duplicate of this bug. ***

@DimitryAndric
Copy link
Collaborator Author

*** Bug llvm/llvm-bugzilla-archive#48803 has been marked as a duplicate of this bug. ***

@DimitryAndric
Copy link
Collaborator Author

*** Bug llvm/llvm-bugzilla-archive#51468 has been marked as a duplicate of this bug. ***

@dyung
Copy link
Collaborator

dyung commented Nov 2, 2021

We recently hit this assertion when investigating an issue internally when compiling with following code with -mno-sse2:

void foo(...) { foo(4.0); }

@DimitryAndric
Copy link
Collaborator Author

mentioned in issue llvm/llvm-bugzilla-archive#37067

@DimitryAndric
Copy link
Collaborator Author

mentioned in issue llvm/llvm-bugzilla-archive#48803

@DimitryAndric
Copy link
Collaborator Author

mentioned in issue llvm/llvm-bugzilla-archive#51468

@phoebewang
Copy link
Contributor

I verified the reported crashes still can be reproduced. I want to have a try to report error instead.

@DimitryAndric
Copy link
Collaborator Author

Yeah it's a very old issue. :) With gcc, depending on the situation, it either just uses old fashioned x87 FP registers, such as with the void fn1(double); int main() { fn1(4.); } test case, or explicitly gives an error "SSE register return with SSE disabled".

Interestingly the assertion only fires when SSE2 is disabled, and not when SSE(1) is disabled.

@RKSimon
Copy link
Collaborator

RKSimon commented Mar 16, 2022

Issue #41013 is very similar - we lost our related bug links in the github transition :-(

@Endilll
Copy link
Contributor

Endilll commented Sep 9, 2023

Another issue: #47305

@MaskRay
Copy link
Member

MaskRay commented Sep 11, 2023

#42679 is also related. I think a major issue is that the behavior of -mno-sse and -mno-sse2 regarding floating-point numbers isn't clear on x86-64. We know that GCC has the error message error: SSE register return with SSE disabled and Clang has implemented it as well, but it is not clear how floating-point arithmetic and floating-point arguments should behave. GCC seems to use a general-purpose register?

Disabling X86FloatingPoint.cpp shall allow Clang to emit assembly, though it's unclear whether the output is desired.

The Linux kernel seems to use -mno-sse -mno-sse2 to disallow floating point numbers, but the actual GCC behavior has some differences from the kernel's intention.

  • reject -mno-sse or -mno-sse2 for x86-64 in the driver: some projects will say that they have legitimate use cases, even if the GCC behavior doesn't match their intention. I think these projects should be fixed to remove -mno-sse/-mno-sse2.
  • reject -mno-sse or -mno-sse2 if float/double is seen: similar to the above as float/double can be in function declarations and unused, or double x; double foo() { return x; } where GCC does something even if the behavior may not match user's expectation.
  • Add more if-fp-bail-out in the X86 backend. This appears to be a difficult whack-a-mole game.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:X86 bugzilla Issues migrated from bugzilla confirmed Verified by a second party crash-on-invalid metabug Issue to collect references to a group of similar or related issues.
Projects
None yet
Development

No branches or pull requests

10 participants