From 23427207ea575f57b571cf5aad1effb1f97e7ee1 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Mon, 18 Nov 2013 13:12:43 +0000 Subject: [PATCH] [mips] Fix 'ran out of registers' in MIPS32 with FP64 when generating code for (ConstantFP 0.0) Fixed an inappropriate use of BuildPairF64 when compiling for MIPS32 with FP64 which resulted in an impossible constraint on the register allocation. It now uses BuildPairF64_64. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195007 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 5 ++++ lib/Target/Mips/MipsSEInstrInfo.cpp | 9 ++++-- test/CodeGen/Mips/2013-11-18-fp64-const0.ll | 31 +++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/Mips/2013-11-18-fp64-const0.ll diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 463c4e90c25..737660ec876 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -634,6 +634,11 @@ std::pair MipsSEDAGToDAGISel::selectNode(SDNode *Node) { SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, Mips::ZERO_64, MVT::i64); Result = CurDAG->getMachineNode(Mips::DMTC1, DL, MVT::f64, Zero); + } else if (Subtarget.isFP64bit()) { + SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, + Mips::ZERO, MVT::i32); + Result = CurDAG->getMachineNode(Mips::BuildPairF64_64, DL, MVT::f64, + Zero, Zero); } else { SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, Mips::ZERO, MVT::i32); diff --git a/lib/Target/Mips/MipsSEInstrInfo.cpp b/lib/Target/Mips/MipsSEInstrInfo.cpp index 2f793348c67..02931a3e39e 100644 --- a/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -520,8 +520,13 @@ void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB, DebugLoc dl = I->getDebugLoc(); const TargetRegisterInfo &TRI = getRegisterInfo(); - // mtc1 Lo, $fp - // mtc1 Hi, $fp + 1 + // For FP32 mode: + // mtc1 Lo, $fp + // mtc1 Hi, $fp + 1 + // For FP64 mode: + // mtc1 Lo, $fp + // mthc1 Hi, $fp + BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_lo)) .addReg(LoReg); diff --git a/test/CodeGen/Mips/2013-11-18-fp64-const0.ll b/test/CodeGen/Mips/2013-11-18-fp64-const0.ll new file mode 100644 index 00000000000..f8390d9a1ca --- /dev/null +++ b/test/CodeGen/Mips/2013-11-18-fp64-const0.ll @@ -0,0 +1,31 @@ +; RUN: llc -march=mips -mattr=-fp64 < %s | FileCheck -check-prefix=CHECK-FP32 %s +; RUN: llc -march=mips -mattr=+fp64 < %s | FileCheck -check-prefix=CHECK-FP64 %s + +; This test case is a simplified version of an llvm-stress generated test with +; seed=3718491962. +; It originally failed on MIPS32 with FP64 with the following error: +; LLVM ERROR: ran out of registers during register allocation +; This was caused by impossible register class restrictions caused by the use +; of BuildPairF64 instead of BuildPairF64_64. + +define void @autogen_SD3718491962() { +BB: + ; CHECK-FP32: mtc1 $zero, $f{{[0-3]*[02468]}} + ; CHECK-FP32: mtc1 $zero, $f{{[0-3]*[13579]}} + + ; CHECK-FP64: mtc1 $zero, $f{{[0-9]+}} + ; CHECK-FP64-NOT: mtc1 $zero, + ; FIXME: A redundant mthc1 is currently emitted. Add a -NOT when it is + ; eliminated + + %Cmp = fcmp ule double 0.000000e+00, undef + %Cmp11 = fcmp ueq double 0xFDBD965CF1BB7FDA, undef + br label %CF88 + +CF88: ; preds = %CF86 + %Sl18 = select i1 %Cmp, i1 %Cmp11, i1 %Cmp + br i1 %Sl18, label %CF88, label %CF85 + +CF85: ; preds = %CF88 + ret void +} -- 2.34.1