[llvm] 5250048 - [Mips] Fix O32 lowering on 64-bit CPUs (#224937)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 20 08:49:17 PDT 2026
Author: Jiaxun Yang
Date: 2026-09-20T16:49:09+01:00
New Revision: 52500486a0b723a1d9528e3098901702da837c3d
URL: https://github.com/llvm/llvm-project/commit/52500486a0b723a1d9528e3098901702da837c3d
DIFF: https://github.com/llvm/llvm-project/commit/52500486a0b723a1d9528e3098901702da837c3d.diff
LOG: [Mips] Fix O32 lowering on 64-bit CPUs (#224937)
Use 32-bit GPR lowering for O32 while preserving the selected ISA and
FPR mode. Handle FP64 transfers through the stack when high-half moves
are unavailable.
Added:
llvm/test/CodeGen/Mips/cconv/o32-fp64-gpr-moves.ll
llvm/test/CodeGen/Mips/cconv/o32-mips64.ll
Modified:
llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
llvm/lib/Target/Mips/MipsSubtarget.cpp
llvm/test/CodeGen/Mips/cconv/arguments-float.ll
llvm/test/CodeGen/Mips/cconv/arguments-struct.ll
llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll
llvm/test/CodeGen/Mips/cconv/arguments.ll
llvm/test/CodeGen/Mips/cconv/callee-saved-float.ll
llvm/test/CodeGen/Mips/cconv/callee-saved.ll
llvm/test/CodeGen/Mips/cconv/memory-layout.ll
llvm/test/CodeGen/Mips/cconv/reserved-space.ll
llvm/test/CodeGen/Mips/cconv/return-float.ll
llvm/test/CodeGen/Mips/cconv/return-hard-float.ll
llvm/test/CodeGen/Mips/cconv/return-struct.ll
llvm/test/CodeGen/Mips/cconv/return.ll
llvm/test/CodeGen/Mips/cconv/stack-alignment.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
index 937e33bd840e6..2aeee5b4e97c9 100644
--- a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
@@ -277,17 +277,17 @@ bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I,
}
/// This method expands the same instruction that MipsSEInstrInfo::
-/// expandBuildPairF64 does, for the case when ABI is fpxx and mthc1 is not
-/// available and the case where the ABI is FP64A. It is implemented here
+/// expandBuildPairF64 does, for FPXX/FP64 when mthc1 is not available and
+/// for FP64A. It is implemented here
/// because frame indexes are eliminated before MipsSEInstrInfo::
/// expandBuildPairF64 is called.
bool ExpandPseudo::expandBuildPairF64(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
bool FP64) const {
- // For fpxx and when mthc1 is not available, use:
+ // For FPXX/FP64 when mthc1 is not available, use:
// spill + reload via ldc1
//
- // The case where dmtc1 is available doesn't need to be handled here
+ // The case where 64-bit GPRs can be used doesn't need to be handled here
// because it never creates a BuildPairF64 node.
//
// The FP64A ABI (fp64 with nooddspreg) must also use a spill/reload sequence
@@ -306,12 +306,6 @@ bool ExpandPseudo::expandBuildPairF64(MachineBasicBlock &MBB,
Register LoReg = I->getOperand(1).getReg();
Register HiReg = I->getOperand(2).getReg();
- // It should be impossible to have FGR64 on MIPS-II or MIPS32r1 (which are
- // the cases where mthc1 is not available). 64-bit architectures and
- // MIPS32r2 or later can use FGR64 though.
- assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||
- !Subtarget.isFP64bit());
-
const TargetRegisterClass *RC = &Mips::GPR32RegClass;
const TargetRegisterClass *RC2 =
FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
@@ -331,8 +325,8 @@ bool ExpandPseudo::expandBuildPairF64(MachineBasicBlock &MBB,
}
/// This method expands the same instruction that MipsSEInstrInfo::
-/// expandExtractElementF64 does, for the case when ABI is fpxx and mfhc1 is not
-/// available and the case where the ABI is FP64A. It is implemented here
+/// expandExtractElementF64 does, for FPXX/FP64 when mfhc1 is not available and
+/// for FP64A. It is implemented here
/// because frame indexes are eliminated before MipsSEInstrInfo::
/// expandExtractElementF64 is called.
bool ExpandPseudo::expandExtractElementF64(MachineBasicBlock &MBB,
@@ -347,10 +341,10 @@ bool ExpandPseudo::expandExtractElementF64(MachineBasicBlock &MBB,
return true;
}
- // For fpxx and when mfhc1 is not available, use:
+ // For FPXX/FP64 when mfhc1 is not available, use:
// spill + reload via ldc1
//
- // The case where dmfc1 is available doesn't need to be handled here
+ // The case where 64-bit GPRs can be used doesn't need to be handled here
// because it never creates a ExtractElementF64 node.
//
// The FP64A ABI (fp64 with nooddspreg) must also use a spill/reload sequence
@@ -370,12 +364,6 @@ bool ExpandPseudo::expandExtractElementF64(MachineBasicBlock &MBB,
unsigned N = Op2.getImm();
int64_t Offset = 4 * (Subtarget.isLittle() ? N : (1 - N));
- // It should be impossible to have FGR64 on MIPS-II or MIPS32r1 (which are
- // the cases where mfhc1 is not available). 64-bit architectures and
- // MIPS32r2 or later can use FGR64 though.
- assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||
- !Subtarget.isFP64bit());
-
const TargetRegisterClass *RC =
FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
const TargetRegisterClass *RC2 = &Mips::GPR32RegClass;
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index 65cec6aa61cad..e3599e268c88e 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
@@ -162,7 +162,7 @@ void MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) {
break;
case Mips::BuildPairF64_64:
case Mips::ExtractElementF64_64:
- if (!Subtarget->useOddSPReg()) {
+ if (!Subtarget->useOddSPReg() || !Subtarget->hasMTHC1()) {
MI.addOperand(MachineOperand::CreateReg(Mips::SP, false, true));
break;
}
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
index b16341dcec0b9..b2062671142f5 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -856,9 +856,9 @@ void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB,
unsigned SubIdx = N ? Mips::sub_hi : Mips::sub_lo;
Register SubReg = getRegisterInfo().getSubReg(SrcReg, SubIdx);
- // FPXX on MIPS-II or MIPS32r1 should have been handled with a spill/reload
+ // FPXX/FP64 without MFHC1 should have been handled with a spill/reload
// in MipsSEFrameLowering.cpp.
- assert(!(Subtarget.isABI_FPXX() && !Subtarget.hasMips32r2()));
+ assert(!((Subtarget.isABI_FPXX() || FP64) && !Subtarget.hasMTHC1()));
// FP64A (FP64 with nooddspreg) should have been handled with a spill/reload
// in MipsSEFrameLowering.cpp.
@@ -899,7 +899,7 @@ void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB,
// mtc1 Lo, $fp
// mthc1 Hi, $fp
//
- // Otherwise, for O32 FPXX ABI:
+ // Otherwise, for FPXX/FP64:
// spill + reload via ldc1
// This case is handled by the frame lowering code.
//
@@ -907,12 +907,12 @@ void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB,
// mtc1 Lo, $fp
// mtc1 Hi, $fp + 1
//
- // The case where dmtc1 is available doesn't need to be handled here
+ // The case where 64-bit GPRs can be used doesn't need to be handled here
// because it never creates a BuildPairF64 node.
- // FPXX on MIPS-II or MIPS32r1 should have been handled with a spill/reload
+ // FPXX/FP64 without MTHC1 should have been handled with a spill/reload
// in MipsSEFrameLowering.cpp.
- assert(!(Subtarget.isABI_FPXX() && !Subtarget.hasMips32r2()));
+ assert(!((Subtarget.isABI_FPXX() || FP64) && !Subtarget.hasMTHC1()));
// FP64A (FP64 with nooddspreg) should have been handled with a spill/reload
// in MipsSEFrameLowering.cpp.
diff --git a/llvm/lib/Target/Mips/MipsSubtarget.cpp b/llvm/lib/Target/Mips/MipsSubtarget.cpp
index 14d507848f2f6..3726a8e04166c 100644
--- a/llvm/lib/Target/Mips/MipsSubtarget.cpp
+++ b/llvm/lib/Target/Mips/MipsSubtarget.cpp
@@ -253,6 +253,11 @@ MipsSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS,
// Parse features string.
ParseSubtargetFeatures(CPUName, /*TuneCPU*/ CPUName, FS);
+
+ // O32 uses 32-bit GPRs even when the selected CPU supports a 64-bit ISA.
+ if (isABI_O32())
+ IsGP64bit = false;
+
if (InMips16Mode && !IsSoftFloat)
InMips16HardFloat = true;
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-float.ll b/llvm/test/CodeGen/Mips/cconv/arguments-float.ll
index 3a39a29de02fe..c639b3edc79cb 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments-float.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments-float.ll
@@ -1,8 +1,8 @@
; RUN: llc -mtriple=mips -relocation-model=static -mattr=+soft-float < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
; RUN: llc -mtriple=mipsel -relocation-model=static -mattr=+soft-float < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
-; RUN-TODO: llc -mtriple=mips64 -relocation-model=static -mattr=+soft-float -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
-; RUN-TODO: llc -mtriple=mips64el -relocation-model=static -mattr=+soft-float -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64 -relocation-model=static -mattr=+soft-float -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el -relocation-model=static -mattr=+soft-float -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
; RUN: llc -mtriple=mips64 -relocation-model=static -mattr=+soft-float -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW %s
; RUN: llc -mtriple=mips64el -relocation-model=static -mattr=+soft-float -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW %s
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-struct.ll b/llvm/test/CodeGen/Mips/cconv/arguments-struct.ll
index 371459f5f85b0..6496e2de227ba 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments-struct.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments-struct.ll
@@ -1,8 +1,8 @@
; RUN: llc -mtriple=mips-unknown-linux-gnu -relocation-model=static < %s | FileCheck --check-prefixes=ALL,SYM32,O32-BE %s
; RUN: llc -mtriple=mipsel-unknown-linux-gnu -relocation-model=static < %s | FileCheck --check-prefixes=ALL,SYM32,O32-LE %s
-; RUN-TODO: llc -mtriple=mips64-unknown-linux-gnu -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32-BE %s
-; RUN-TODO: llc -mtriple=mips64el-unknown-linux-gnu -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32-LE %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64-unknown-linux-gnu -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32-BE %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el-unknown-linux-gnu -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32-LE %s
; RUN: llc -mtriple=mips64-unknown-linux-gnu -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW-BE %s
; RUN: llc -mtriple=mips64el-unknown-linux-gnu -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW-LE %s
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll b/llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll
index 1f97b376c290b..b87d27489bd0f 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll
@@ -3,10 +3,10 @@
; RUN: llc -mtriple=mipsel-linux -relocation-model=static < %s \
; RUN: | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64 -relocation-model=static -target-abi o32 < %s \
-; RUN-TODO: | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64el -relocation-model=static -target-abi o32 < %s \
-; RUN-TODO: | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64 -relocation-model=static -target-abi o32 < %s \
+; RUN: | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el -relocation-model=static -target-abi o32 < %s \
+; RUN: | FileCheck --check-prefixes=ALL,O32 %s
; RUN: llc -mtriple=mips64-linux -relocation-model=static -target-abi n32 < %s \
; RUN: | FileCheck --check-prefixes=ALL,NEW,N32,NEW-BE %s
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments.ll b/llvm/test/CodeGen/Mips/cconv/arguments.ll
index 75403ec8a4657..4621f8e66e49e 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments.ll
@@ -1,8 +1,8 @@
; RUN: llc -mtriple=mips -relocation-model=static < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
; RUN: llc -mtriple=mipsel -relocation-model=static < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
-; RUN-TODO: llc -mtriple=mips64 -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
-; RUN-TODO: llc -mtriple=mips64el -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64 -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
; RUN: llc -mtriple=mips64 -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW %s
; RUN: llc -mtriple=mips64el -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW %s
diff --git a/llvm/test/CodeGen/Mips/cconv/callee-saved-float.ll b/llvm/test/CodeGen/Mips/cconv/callee-saved-float.ll
index 14d781dc57df8..07899b6b76a8e 100644
--- a/llvm/test/CodeGen/Mips/cconv/callee-saved-float.ll
+++ b/llvm/test/CodeGen/Mips/cconv/callee-saved-float.ll
@@ -3,10 +3,10 @@
; RUN: llc -mtriple=mips < %s | FileCheck --check-prefixes=ALL,O32-INV %s
; RUN: llc -mtriple=mipsel < %s | FileCheck --check-prefixes=ALL,O32-INV %s
-; RUN-TODO: llc -mtriple=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,ALL-INV,O32-INV %s
-; RUN-TODO: llc -mtriple=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,ALL-INV,O32-INV %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,ALL-INV,O32-INV %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,ALL-INV,O32-INV %s
; RUN: llc -mtriple=mips64 -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
; RUN: llc -mtriple=mips64el -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
diff --git a/llvm/test/CodeGen/Mips/cconv/callee-saved.ll b/llvm/test/CodeGen/Mips/cconv/callee-saved.ll
index 93808fbcad03d..c0223ae0c8c27 100644
--- a/llvm/test/CodeGen/Mips/cconv/callee-saved.ll
+++ b/llvm/test/CodeGen/Mips/cconv/callee-saved.ll
@@ -3,14 +3,14 @@
; RUN: llc -mtriple=mips < %s | FileCheck --check-prefixes=ALL,O32-INV %s
; RUN: llc -mtriple=mipsel < %s | FileCheck --check-prefixes=ALL,O32-INV %s
-; RUN-TODO: llc -mtriple=mips64 -target-abi o32 < %s \
-; RUN-TODO: | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64el -target-abi o32 < %s \
-; RUN-TODO: | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64 -target-abi o32 < %s \
-; RUN-TODO: | FileCheck --check-prefixes=ALL,O32-INV %s
-; RUN-TODO: llc -mtriple=mips64el -target-abi o32 < %s \
-; RUN-TODO: | FileCheck --check-prefixes=ALL,O32-INV %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64 -target-abi o32 < %s \
+; RUN: | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el -target-abi o32 < %s \
+; RUN: | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64 -target-abi o32 < %s \
+; RUN: | FileCheck --check-prefixes=ALL,O32-INV %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el -target-abi o32 < %s \
+; RUN: | FileCheck --check-prefixes=ALL,O32-INV %s
; RUN: llc -mtriple=mips64 -target-abi n32 < %s \
; RUN: | FileCheck --check-prefixes=ALL,N32 %s
diff --git a/llvm/test/CodeGen/Mips/cconv/memory-layout.ll b/llvm/test/CodeGen/Mips/cconv/memory-layout.ll
index c95fe09de20e7..ceaaa832e6747 100644
--- a/llvm/test/CodeGen/Mips/cconv/memory-layout.ll
+++ b/llvm/test/CodeGen/Mips/cconv/memory-layout.ll
@@ -1,8 +1,8 @@
; RUN: llc -mtriple=mips-elf < %s | FileCheck --check-prefixes=ALL,O32 %s
; RUN: llc -mtriple=mipsel-elf < %s | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64-elf -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64el-elf -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64-elf -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el-elf -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
; RUN: llc -mtriple=mips64-elf -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
; RUN: llc -mtriple=mips64el-elf -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
diff --git a/llvm/test/CodeGen/Mips/cconv/o32-fp64-gpr-moves.ll b/llvm/test/CodeGen/Mips/cconv/o32-fp64-gpr-moves.ll
new file mode 100644
index 0000000000000..b6d7dde52852e
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/cconv/o32-fp64-gpr-moves.ll
@@ -0,0 +1,63 @@
+; RUN: llc -mtriple=mips64 -mcpu=mips3 -target-abi=o32 -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64el -mcpu=mips3 -target-abi=o32 -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64 -mcpu=mips4 -target-abi=o32 -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64el -mcpu=mips4 -target-abi=o32 -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64 -mcpu=mips64 -target-abi=o32 -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64el -mcpu=mips64 -target-abi=o32 -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64 -mcpu=mips64r2 -target-abi=o32 -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64el -mcpu=mips64r2 -target-abi=o32 -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64 -mcpu=mips64r6 -target-abi=o32 -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64el -mcpu=mips64r6 -target-abi=o32 -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64 -mcpu=mips64 -target-abi=o32 -mattr=+nooddspreg -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64el -mcpu=mips64 -target-abi=o32 -mattr=+nooddspreg -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64 -mcpu=mips64r2 -target-abi=o32 -mattr=+nooddspreg -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64el -mcpu=mips64r2 -target-abi=o32 -mattr=+nooddspreg -verify-machineinstrs -filetype=obj %s -o /dev/null
+; RUN: llc -mtriple=mips64 -mcpu=mips64 -target-abi=o32 -verify-machineinstrs < %s | FileCheck %s --check-prefix=SPILL
+; RUN: llc -mtriple=mips64el -mcpu=mips64 -target-abi=o32 -verify-machineinstrs < %s | FileCheck %s --check-prefix=SPILL
+; RUN: llc -mtriple=mips64 -mcpu=mips64r2 -target-abi=o32 -verify-machineinstrs < %s | FileCheck %s --check-prefix=DIRECT-BE
+; RUN: llc -mtriple=mips64el -mcpu=mips64r2 -target-abi=o32 -verify-machineinstrs < %s | FileCheck %s --check-prefix=DIRECT-LE
+
+; An integer argument before a double makes O32 pass that double in two
+; 32-bit GPRs. Check both directions of the transfer with 64-bit FPRs.
+; Before revision 2, MTHC1/MFHC1 are unavailable: the upper half of an FPR
+; cannot be accessed by applying MTC1/MFC1 to its sub_hi register.
+define double @from_gprs(i32 %pad, double %value) {
+; SPILL-LABEL: from_gprs:
+; SPILL: addiu $sp, $sp, -8
+; SPILL: sw $6, 0($sp)
+; SPILL-NEXT: sw $7, 4($sp)
+; SPILL-NEXT: ldc1 $f0, 0($sp)
+; SPILL: addiu $sp, $sp, 8
+;
+; DIRECT-BE-LABEL: from_gprs:
+; DIRECT-BE: mtc1 $7, $f0
+; DIRECT-BE-NEXT: mthc1 $6, $f0
+;
+; DIRECT-LE-LABEL: from_gprs:
+; DIRECT-LE: mtc1 $6, $f0
+; DIRECT-LE-NEXT: mthc1 $7, $f0
+ ret double %value
+}
+
+declare void @consume(i32, double)
+
+define void @to_gprs(double %value) {
+; SPILL-LABEL: to_gprs:
+; SPILL: sdc1 $f12, 16($sp)
+; SPILL-NEXT: lw $6, 16($sp)
+; SPILL-NEXT: sdc1 $f12, 16($sp)
+; SPILL-NEXT: lw $7, 20($sp)
+; SPILL: jal consume
+;
+; DIRECT-BE-LABEL: to_gprs:
+; DIRECT-BE-DAG: mfhc1 $6, $f12
+; DIRECT-BE-DAG: mfc1 $7, $f12
+; DIRECT-BE: jal consume
+;
+; DIRECT-LE-LABEL: to_gprs:
+; DIRECT-LE-DAG: mfc1 $6, $f12
+; DIRECT-LE-DAG: mfhc1 $7, $f12
+; DIRECT-LE: jal consume
+ call void @consume(i32 1, double %value)
+ ret void
+}
diff --git a/llvm/test/CodeGen/Mips/cconv/o32-mips64.ll b/llvm/test/CodeGen/Mips/cconv/o32-mips64.ll
new file mode 100644
index 0000000000000..be4b0f914cc2e
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/cconv/o32-mips64.ll
@@ -0,0 +1,124 @@
+; RUN: llc -mtriple=mips64 -target-abi=o32 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=BE,HARD
+; RUN: llc -mtriple=mips64el -target-abi=o32 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=LE,HARD
+; RUN: llc -mtriple=mips64 -target-abi=o32 -mattr=+soft-float -verify-machineinstrs < %s | FileCheck %s --check-prefixes=BE,SOFT-BE
+; RUN: llc -mtriple=mips64el -target-abi=o32 -mattr=+soft-float -verify-machineinstrs < %s | FileCheck %s --check-prefixes=LE,SOFT-LE
+; RUN: llc -mtriple=mips64 -mcpu=mips64r2 -target-abi=o32 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=ALL,O32-BE
+; RUN: llc -mtriple=mips64el -mcpu=mips64r2 -target-abi=o32 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=ALL,O32-LE
+; RUN: llc -mtriple=mips64 -mcpu=mips64r2 -target-abi=n32 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=ALL,NABI
+; RUN: llc -mtriple=mips64el -mcpu=mips64r2 -target-abi=n32 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=ALL,NABI
+; RUN: llc -mtriple=mips64 -mcpu=mips64r2 -target-abi=n64 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=ALL,NABI
+; RUN: llc -mtriple=mips64el -mcpu=mips64r2 -target-abi=n64 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=ALL,NABI
+
+; Selecting O32's GPR mode must preserve the CPU's revision 2 instructions
+; and 64-bit FPR mode. N32/N64 must continue to use 64-bit GPR operations.
+; O32-BE: .module fp=64
+; O32-LE: .module fp=64
+
+declare i32 @llvm.fshr.i32(i32, i32, i32)
+
+define i32 @rotate(i32 %value) {
+; ALL-LABEL: rotate:
+; O32-BE: rotr $2, $4, 7
+; O32-LE: rotr $2, $4, 7
+; NABI: sll [[WORD:\$[0-9]+]], $4, 0
+; NABI: rotr $2, [[WORD]], 7
+ %result = call i32 @llvm.fshr.i32(i32 %value, i32 %value, i32 7)
+ ret i32 %result
+}
+
+define double @add_double(double %x, double %y) {
+; ALL-LABEL: add_double:
+; O32-BE: add.d $f0, $f12, $f14
+; O32-LE: add.d $f0, $f12, $f14
+; NABI: add.d $f0, $f12, $f13
+ %result = fadd double %x, %y
+ ret double %result
+}
+
+define i64 @increment(i64 %value) {
+; ALL-LABEL: increment:
+; O32-BE: addiu $3, $5, 1
+; O32-BE: sltiu $1, $3, 1
+; O32-BE: addu $2, $4, $1
+; O32-LE: addiu $2, $4, 1
+; O32-LE: sltiu $1, $2, 1
+; O32-LE: addu $3, $5, $1
+; NABI: daddiu $2, $4, 1
+ %result = add i64 %value, 1
+ ret i64 %result
+}
+
+; O32 passes and returns i64 in pairs of 32-bit registers even on a 64-bit
+; CPU. The caller and callee must agree on the pieces.
+define i64 @identity_i64(i64 %value) {
+; BE-LABEL: identity_i64:
+; BE: # %bb.0:
+; BE-NEXT: move $2, $4
+; BE-NEXT: jr $ra
+; BE-NEXT: move $3, $5
+;
+; LE-LABEL: identity_i64:
+; LE: # %bb.0:
+; LE-NEXT: move $2, $4
+; LE-NEXT: jr $ra
+; LE-NEXT: move $3, $5
+ ret i64 %value
+}
+
+declare i64 @get_i64()
+
+define i64 @call_i64() {
+; BE-LABEL: call_i64:
+; BE: # %bb.0:
+; BE-NEXT: addiu $sp, $sp, -24
+; BE-NEXT: .cfi_def_cfa_offset 24
+; BE-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
+; BE-NEXT: .cfi_offset 31, -4
+; BE-NEXT: jal get_i64
+; BE-NEXT: nop
+; BE-NEXT: addiu $3, $3, 1
+; BE-NEXT: sltiu $1, $3, 1
+; BE-NEXT: addu $2, $2, $1
+; BE-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
+; BE-NEXT: jr $ra
+; BE-NEXT: addiu $sp, $sp, 24
+;
+; LE-LABEL: call_i64:
+; LE: # %bb.0:
+; LE-NEXT: addiu $sp, $sp, -24
+; LE-NEXT: .cfi_def_cfa_offset 24
+; LE-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
+; LE-NEXT: .cfi_offset 31, -4
+; LE-NEXT: jal get_i64
+; LE-NEXT: nop
+; LE-NEXT: addiu $2, $2, 1
+; LE-NEXT: sltiu $1, $2, 1
+; LE-NEXT: addu $3, $3, $1
+; LE-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
+; LE-NEXT: jr $ra
+; LE-NEXT: addiu $sp, $sp, 24
+ %value = call i64 @get_i64()
+ %result = add i64 %value, 1
+ ret i64 %result
+}
+
+; Soft-float doubles use the same integer register pairs.
+define double @identity_double(double %value) {
+; HARD-LABEL: identity_double:
+; HARD: # %bb.0:
+; HARD-NEXT: jr $ra
+; HARD-NEXT: mov.d $f0, $f12
+;
+; SOFT-BE-LABEL: identity_double:
+; SOFT-BE: # %bb.0:
+; SOFT-BE-NEXT: move $2, $4
+; SOFT-BE-NEXT: jr $ra
+; SOFT-BE-NEXT: move $3, $5
+;
+; SOFT-LE-LABEL: identity_double:
+; SOFT-LE: # %bb.0:
+; SOFT-LE-NEXT: move $2, $4
+; SOFT-LE-NEXT: jr $ra
+; SOFT-LE-NEXT: move $3, $5
+ ret double %value
+}
diff --git a/llvm/test/CodeGen/Mips/cconv/reserved-space.ll b/llvm/test/CodeGen/Mips/cconv/reserved-space.ll
index 490476961626e..b86ba808f11f9 100644
--- a/llvm/test/CodeGen/Mips/cconv/reserved-space.ll
+++ b/llvm/test/CodeGen/Mips/cconv/reserved-space.ll
@@ -1,8 +1,8 @@
; RUN: llc -mtriple=mips < %s | FileCheck --check-prefixes=ALL,O32 %s
; RUN: llc -mtriple=mipsel < %s | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
; RUN: llc -mtriple=mips64 -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
; RUN: llc -mtriple=mips64el -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
diff --git a/llvm/test/CodeGen/Mips/cconv/return-float.ll b/llvm/test/CodeGen/Mips/cconv/return-float.ll
index 8b9be38179acf..3fe583546ec26 100644
--- a/llvm/test/CodeGen/Mips/cconv/return-float.ll
+++ b/llvm/test/CodeGen/Mips/cconv/return-float.ll
@@ -1,8 +1,8 @@
; RUN: llc -mtriple=mips-linux-gnu -mattr=+soft-float -relocation-model=static < %s | FileCheck --check-prefixes=ALL,O32 %s
; RUN: llc -mtriple=mipsel-linux-gnu -mattr=+soft-float -relocation-model=static < %s | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64-linux-gnu -mattr=+soft-float -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64el-linux-gnu -mattr=+soft-float -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64-linux-gnu -mattr=+soft-float -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el-linux-gnu -mattr=+soft-float -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
; RUN: llc -mtriple=mips64-linux-gnu -mattr=+soft-float -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
; RUN: llc -mtriple=mips64el-linux-gnu -mattr=+soft-float -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
diff --git a/llvm/test/CodeGen/Mips/cconv/return-hard-float.ll b/llvm/test/CodeGen/Mips/cconv/return-hard-float.ll
index 5f2aeee09f398..0043faff2dfc1 100644
--- a/llvm/test/CodeGen/Mips/cconv/return-hard-float.ll
+++ b/llvm/test/CodeGen/Mips/cconv/return-hard-float.ll
@@ -3,10 +3,10 @@
; RUN: llc -mtriple=mipsel-linux-gnu -relocation-model=static < %s \
; RUN: | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64-linux-gnu -relocation-model=static -target-abi o32 < %s \
-; RUN-TODO: | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64el-linux-gnu -relocation-model=static -target-abi o32 < %s \
-; RUN-TODO: | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64-linux-gnu -relocation-model=static -target-abi o32 < %s \
+; RUN: | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el-linux-gnu -relocation-model=static -target-abi o32 < %s \
+; RUN: | FileCheck --check-prefixes=ALL,O32 %s
; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=static -target-abi n32 < %s \
; RUN: | FileCheck --check-prefixes=ALL,N32 %s
diff --git a/llvm/test/CodeGen/Mips/cconv/return-struct.ll b/llvm/test/CodeGen/Mips/cconv/return-struct.ll
index 68f8127ae9f13..109e160161f54 100644
--- a/llvm/test/CodeGen/Mips/cconv/return-struct.ll
+++ b/llvm/test/CodeGen/Mips/cconv/return-struct.ll
@@ -4,10 +4,10 @@
; RUN: llc -mtriple=mipsel-linux-gnu -relocation-model=static < %s \
; RUN: | FileCheck --check-prefixes=O32,O32-LE %s
-; RUN-TODO: llc -mtriple=mips64-linux-gnu -relocation-model=static -target-abi o32 < %s \
-; RUN-TODO: | FileCheck --check-prefixes=O32 %s
-; RUN-TODO: llc -mtriple=mips64el-linux-gnu -relocation-model=static -target-abi o32 < %s \
-; RUN-TODO: | FileCheck --check-prefixes=O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64-linux-gnu -relocation-model=static -target-abi o32 < %s \
+; RUN: | FileCheck --check-prefixes=O32,O32-BE %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el-linux-gnu -relocation-model=static -target-abi o32 < %s \
+; RUN: | FileCheck --check-prefixes=O32,O32-LE %s
; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=static -target-abi n32 < %s \
; RUN: | FileCheck --check-prefixes=N32,N32-BE %s
diff --git a/llvm/test/CodeGen/Mips/cconv/return.ll b/llvm/test/CodeGen/Mips/cconv/return.ll
index f0e4545bd4559..c9fc8de3a96fe 100644
--- a/llvm/test/CodeGen/Mips/cconv/return.ll
+++ b/llvm/test/CodeGen/Mips/cconv/return.ll
@@ -1,8 +1,8 @@
; RUN: llc -mtriple=mips-linux-gnu -relocation-model=static < %s | FileCheck --check-prefixes=ALL,O32 %s
; RUN: llc -mtriple=mipsel-linux-gnu -relocation-model=static < %s | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64-linux-gnu -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64el-linux-gnu -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=static -target-abi o32 -verify-machineinstrs < %s | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -mtriple=mips64el-linux-gnu -relocation-model=static -target-abi o32 -verify-machineinstrs < %s | FileCheck --check-prefixes=ALL,O32 %s
; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
; RUN: llc -mtriple=mips64el-linux-gnu -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
diff --git a/llvm/test/CodeGen/Mips/cconv/stack-alignment.ll b/llvm/test/CodeGen/Mips/cconv/stack-alignment.ll
index 9cdb8428b484a..9e93f0396e397 100644
--- a/llvm/test/CodeGen/Mips/cconv/stack-alignment.ll
+++ b/llvm/test/CodeGen/Mips/cconv/stack-alignment.ll
@@ -1,8 +1,8 @@
; RUN: llc -mtriple=mips < %s | FileCheck --check-prefixes=ALL,O32 %s
; RUN: llc -mtriple=mipsel < %s | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
-; RUN-TODO: llc -mtriple=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
+; RUN: llc -verify-machineinstrs -mtriple=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
; RUN: llc -mtriple=mips64 -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
; RUN: llc -mtriple=mips64el -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
More information about the llvm-commits
mailing list