-
Notifications
You must be signed in to change notification settings - Fork 13.5k
unsigned int getFPReg(const llvm::MachineOperand&): Assertion `Reg >= X86::FP0 && Reg <= X86::FP6 && "Expected FP register!"' fa #10870
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
Comments
These are great bugs, but please put the test-case in an attachment so it won't be mangled by Bugzilla. |
Okay. I will also clean-up my random test generator and add it to llvm/util.
|
I am not sure if this test case is valid. It is trying to call a function that takes arguments in %xmm0 and %xmm1, but sse2 is disabled. We keep our floats in x87 registers, and try to set up the call like this:
Eli, what do you think? Should this work with -mattr=-sse2,-sse41? |
The original IR doesn't contain any call instructions, it only makes use of |
Might be "valid", but we have no sane way to generate frem on x86-64 with sse forced off. Granted, there is a missing report_fatal_error call in X86TargetLowering::LowerCall which would make that much more clear. |
Maybe this can help: https://reviews.llvm.org/D27522. |
Reduced test case |
"+sse,-sse2"? How did the function get a feature list like that? If clang is generating that, I'd consider it a bug in clang. Granted, we should still print a reasonable error from the backend. |
It's the -mno-sse2 flag. Here is a simple reproducer: echo "double add(double a, double b) {return a + b;}" | clang -mno-sse2 -c -x c - |
The backend does raise an error in X86TargetLowering::LowerReturn() by calling errorUnsupported(DAG, dl, "SSE2 register return with SSE2 disabled"); But then the backend asserts in a later pass before clang can handle the error. |
Hello friends! I hit precisely this assertion today debugging crash when compiling the Linux kernel w/ Clang. The kernel disables -msse (and all newer x86 ISA extensions) as it would otherwise have to save/restore FP registers. It does allow for limited use of -msse to few drivers, but Clang crashes generating code for them. $ cat foo.i
|
Some observations from a debugger: llvm/lib/Target/X86/X86FloatingPoint.cpp#FPS::processBasicBlock() calls llvm/lib/Target/X86/X86FloatingPoint.cpp#FPS::handleSpecialFP() calls llvm/lib/Target/X86/X86FloatingPoint.cpp#getFPReg() for the MachineInstruction: renamable $fp0 = COPY killed $xmm0 AFAICT, this instruction exists as soon as the LLVM bitcode is invoked with FPS::processBasicBlock() has a bunch of special cases that set FPInstClass = X86II::SpecialFP; maybe one of those is wrong? Specifically,
is true. Maybe the assertion everyone is hitting should be relaxed for all FP regs added via ISA extensions, or the |
So llvm/lib/Target/X86/X86FloatingPoint.cpp#FPS::runOnMachineFunction() is a curious case. It has a check that FP regs are used:
For the first loop iteration 64B %1:rfp64 = COPY killed $xmm0 into 64B renamable $fp0 = COPY killed $xmm0 which later leads to the assertion failure. Not that I know anything about MIR, but should the VRR rewrite rfp64 into another $xmm register (based on the instruction's operand) or should %rfp64 virtual operator ever be emitted for a |
A copy from $xmm0 to an x87 register should never be generated. There are no instructions that can directly make the copy. The explicit reference to the xmm0 register is to match the ABI for the return from the call. The intention normally is that the xmm0 register will be copied to a virtual register of FR64 class which will give freedom back to the register allocator. Since SSE2 is disabled the register class assigned to f64 is RFP64 instead of FR64. So we generate a bogus call. I have a patch to stop the assertion, but it will generate an error instead. Removing the error is going to be harder and I'm not sure how to do it exactly. |
Craig fixed up the compiler crash from my test case in comment #11 in r372197. Here are a few more simple test cases that also lead to compiler crashes at -mno-sse2: https://godbolt.org/z/HUwLYg |
mentioned in issue llvm/llvm-bugzilla-archive#30426 |
Extended Description
llc: X86FloatingPoint.cpp:316: unsigned int getFPReg(const llvm::MachineOperand&): Assertion `Reg >= X86::FP0 && Reg <= X86::FP6 && "Expected FP register!"' failed.
0 llc 0x000000000153ffea
1 llc 0x0000000001540578
2 libpthread.so.0 0x00002aaaaabd4d60
3 libc.so.6 0x00002aaaab274f45 gsignal + 53
4 libc.so.6 0x00002aaaab276340 abort + 272
5 libc.so.6 0x00002aaaab26e486 __assert_fail + 246
6 llc 0x0000000000e542c8
7 llc 0x0000000000e5606a (anonymous namespace)::FPS::handleSpecialFP(llvm::ilist_iteratorllvm::MachineInstr&) + 1412
8 llc 0x0000000000e57f27 (anonymous namespace)::FPS::processBasicBlock(llvm::MachineFunction&, llvm::MachineBasicBlock&) + 885
9 llc 0x0000000000e58459 (anonymous namespace)::FPS::runOnMachineFunction(llvm::MachineFunction&) + 341
10 llc 0x00000000011449ad llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 85
11 llc 0x000000000147a2bb llvm::FPPassManager::runOnFunction(llvm::Function&) + 371
12 llc 0x000000000147a4b3 llvm::FPPassManager::runOnModule(llvm::Module&) + 81
13 llc 0x0000000001479f67 llvm::MPPassManager::runOnModule(llvm::Module&) + 381
14 llc 0x000000000147b71c llvm::PassManagerImpl::run(llvm::Module&) + 116
15 llc 0x000000000147b77f llvm::PassManager::run(llvm::Module&) + 33
16 llc 0x0000000000ab642d main + 2403
17 libc.so.6 0x00002aaaab262304 __libc_start_main + 244
18 llc 0x0000000000ab4b79
Stack dump:
0. Program arguments: ../llc temp.ll -march=x86-64 -mattr=-sse2,-sse41 -o /dev/null
; ModuleID = 'bugpoint-reduced-simplified.bc'
target triple = "x86_64-unknown-linux-gnu"
define void @autogen_9448_500(i8*, i32*, i64*, i32, i8, i64) {
BB:
%A4 = alloca <8 x i64>
%A3 = alloca <8 x i8>
%A2 = alloca <8 x i8>
%A1 = alloca <8 x i32>
%A = alloca <8 x double>
%L = load i8* %0
store i8 -89, i8* %0
%E = extractelement <8 x i32> undef, i32 7
%E5 = extractelement <32 x float> undef, i32 12
%Shuff = shufflevector <8 x double> undef, <8 x double> undef, <8 x i32> <i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 undef, i32 undef>
%Shuff6 = shufflevector <8 x double> %Shuff, <8 x double> %Shuff, <8 x i32> <i32 4, i32 6, i32 8, i32 10, i32 12, i32 undef, i32 0, i32 undef>
%Shuff7 = shufflevector <8 x double> %Shuff, <8 x double> %Shuff, <8 x i32> <i32 6, i32 8, i32 10, i32 12, i32 14, i32 0, i32 2, i32 4>
%I = insertelement <8 x double> %Shuff, double 0x3EC3137F3F602019, i32 0
%B = mul i8 %L, -1
%FC = fptosi double 0x3EC3137F3F602019 to i16
%S = select i1 true, i16 %FC, i16 %FC
%S8 = fcmp olt float %E5, 0x3EC6F41020000000
br label %CF42
CF42: ; preds = %BB
%L9 = load i8* %0
store i8 %L, i8* %0
%E10 = extractelement <8 x double> %Shuff, i32 6
%E11 = extractelement <8 x double> %Shuff, i32 0
%Shuff12 = shufflevector <8 x double> %Shuff, <8 x double> %Shuff, <8 x i32> <i32 3, i32 5, i32 undef, i32 9, i32 11, i32 undef, i32 15, i32 1>
%Shuff13 = shufflevector <8 x double> %Shuff, <8 x double> %Shuff, <8 x i32> <i32 undef, i32 undef, i32 9, i32 11, i32 13, i32 15, i32 undef, i32 3>
%Shuff14 = shufflevector <8 x double> %Shuff, <8 x double> %Shuff13, <8 x i32> <i32 7, i32 undef, i32 11, i32 13, i32 15, i32 1, i32 undef, i32 5>
%I15 = insertelement <8 x double> %Shuff12, double 0x3ED4B999595A3E38, i32 1
%B16 = frem <8 x double> %Shuff13, %Shuff
%BC = bitcast float 0x3ECCE7D580000000 to i32
%S17 = select i1 true, i64 -1, i64 %5
%S18 = icmp ule i64 508019, %S17
br label %CF41
CF41: ; preds = %CF41, %CF42
%L19 = load i8* %0
store i8 -1, i8* %0
%E20 = extractelement <8 x double> %Shuff, i32 1
%E21 = extractelement <8 x double> %Shuff, i32 3
%Shuff22 = shufflevector <8 x double> %Shuff, <8 x double> %Shuff, <8 x i32> <i32 undef, i32 undef, i32 2, i32 4, i32 6, i32 8, i32 10, i32 undef>
%Shuff23 = shufflevector <8 x double> %Shuff, <8 x double> %Shuff, <8 x i32> <i32 0, i32 2, i32 4, i32 undef, i32 8, i32 undef, i32 undef, i32 14>
%Shuff24 = shufflevector <8 x double> %Shuff, <8 x double> %Shuff12, <8 x i32> <i32 2, i32 4, i32 6, i32 undef, i32 10, i32 12, i32 undef, i32 0>
%I25 = insertelement <8 x double> %Shuff, double %E10, i32 4
%B26 = fdiv <8 x double> %B16, %Shuff
%FC27 = sitofp i32 338935 to float
%S28 = select i1 false, i32* %1, i32* %1
%S29 = icmp slt i8 -1, %B
br i1 %S29, label %CF41, label %CF43
CF43: ; preds = %CF41
%L30 = load i32* %S28
store i32 413419, i32* %S28
%E31 = extractelement <8 x double> %Shuff6, i32 2
%E32 = extractelement <8 x double> %Shuff, i32 4
%Shuff33 = shufflevector <8 x double> %Shuff12, <8 x double> %Shuff, <8 x i32> <i32 7, i32 9, i32 11, i32 undef, i32 15, i32 1, i32 3, i32 5>
%Shuff34 = shufflevector <8 x double> %Shuff, <8 x double> %Shuff, <8 x i32> <i32 9, i32 undef, i32 13, i32 undef, i32 1, i32 3, i32 5, i32 7>
%Shuff35 = shufflevector <8 x double> %Shuff, <8 x double> %Shuff, <8 x i32> <i32 11, i32 13, i32 15, i32 1, i32 3, i32 5, i32 7, i32 undef>
%I36 = insertelement <8 x double> %Shuff, double %E10, i32 5
%B37 = fadd <8 x double> %Shuff14, %Shuff
%FC38 = uitofp i8 -89 to double
%S39 = select i1 true, <8 x double>* %A, <8 x double>* %A
%S40 = icmp slt i32 413419, 0
br label %CF
CF: ; preds = %CF43
store <8 x double> %Shuff12, <8 x double>* %A
store i32 %3, i32* %S28
store i32 %3, i32* %S28
store <8 x double> %Shuff, <8 x double>* %A
store <8 x double> %Shuff33, <8 x double>* %S39
ret void
}
The text was updated successfully, but these errors were encountered: