[llvm] [Mips] Add support for Mips::GPR64Idx in MipsRegisterBankInfo (PR #173534)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 25 01:18:22 PST 2025
https://github.com/yingopq created https://github.com/llvm/llvm-project/pull/173534
Fix #166002.
>From 0e473dc01626e31510105b291979b880d7fdeb70 Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Thu, 25 Dec 2025 11:14:13 +0800
Subject: [PATCH] [Mips] Add support for Mips::GPR64Idx in MipsRegisterBankInfo
Fix #166002.
---
.../Target/Mips/MipsInstructionSelector.cpp | 8 +-
llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp | 132 +++++++++---------
llvm/lib/Target/Mips/MipsRegisterBankInfo.h | 6 +
llvm/lib/Target/Mips/MipsRegisterBanks.td | 2 +-
.../GlobalISel/llvm-ir/implicit_def_mips64.ll | 13 ++
5 files changed, 93 insertions(+), 68 deletions(-)
create mode 100644 llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/implicit_def_mips64.ll
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
index 332749165a3ff..bd02b57bfc860 100644
--- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
+++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
@@ -123,9 +123,13 @@ const TargetRegisterClass *MipsInstructionSelector::getRegClassForTypeOnBank(
const unsigned TySize = Ty.getSizeInBits();
if (isRegInGprb(Reg, MRI)) {
- assert((Ty.isScalar() || Ty.isPointer()) && TySize == 32 &&
+ assert((Ty.isScalar() || Ty.isPointer()) &&
+ (TySize == 32 || TySize == 64) &&
"Register class not available for LLT, register bank combination");
- return &Mips::GPR32RegClass;
+ if (TySize == 32)
+ return &Mips::GPR32RegClass;
+ if (TySize == 64)
+ return &Mips::GPR64RegClass;
}
if (isRegInFprb(Reg, MRI)) {
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
index 8e791e6986272..5541fcd65cb25 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
@@ -25,35 +25,40 @@
namespace llvm {
namespace Mips {
enum PartialMappingIdx {
- PMI_GPR,
+ PMI_GPR32,
+ PMI_GPR64,
PMI_SPR,
PMI_DPR,
PMI_MSA,
- PMI_Min = PMI_GPR,
+ PMI_Min = PMI_GPR32,
};
-const RegisterBankInfo::PartialMapping PartMappings[]{
- {0, 32, GPRBRegBank},
- {0, 32, FPRBRegBank},
- {0, 64, FPRBRegBank},
- {0, 128, FPRBRegBank}
-};
+const RegisterBankInfo::PartialMapping PartMappings[]{{0, 32, GPRBRegBank},
+ {0, 64, GPRBRegBank},
+ {0, 32, FPRBRegBank},
+ {0, 64, FPRBRegBank},
+ {0, 128, FPRBRegBank}};
enum ValueMappingIdx {
- InvalidIdx = 0,
- GPRIdx = 1,
- SPRIdx = 4,
- DPRIdx = 7,
- MSAIdx = 10
+ InvalidIdx = 0,
+ GPR32Idx = 1,
+ GPR64Idx = 4,
+ SPRIdx = 7,
+ DPRIdx = 10,
+ MSAIdx = 13
};
const RegisterBankInfo::ValueMapping ValueMappings[] = {
// invalid
{nullptr, 0},
- // up to 3 operands in GPRs
- {&PartMappings[PMI_GPR - PMI_Min], 1},
- {&PartMappings[PMI_GPR - PMI_Min], 1},
- {&PartMappings[PMI_GPR - PMI_Min], 1},
+ // up to 3 operands in GPRs; 32 bit.
+ {&PartMappings[PMI_GPR32 - PMI_Min], 1},
+ {&PartMappings[PMI_GPR32 - PMI_Min], 1},
+ {&PartMappings[PMI_GPR32 - PMI_Min], 1},
+ // up to 3 operands in GPRs; 64 bit.
+ {&PartMappings[PMI_GPR64 - PMI_Min], 1},
+ {&PartMappings[PMI_GPR64 - PMI_Min], 1},
+ {&PartMappings[PMI_GPR64 - PMI_Min], 1},
// up to 3 operands in FPRs - single precission
{&PartMappings[PMI_SPR - PMI_Min], 1},
{&PartMappings[PMI_SPR - PMI_Min], 1},
@@ -65,8 +70,7 @@ const RegisterBankInfo::ValueMapping ValueMappings[] = {
// up to 3 operands in FPRs - MSA
{&PartMappings[PMI_MSA - PMI_Min], 1},
{&PartMappings[PMI_MSA - PMI_Min], 1},
- {&PartMappings[PMI_MSA - PMI_Min], 1}
-};
+ {&PartMappings[PMI_MSA - PMI_Min], 1}};
} // end namespace Mips
} // end namespace llvm
@@ -366,7 +370,7 @@ static const unsigned CustomMappingID = 1;
static const MipsRegisterBankInfo::ValueMapping *
getGprbOrCustomMapping(unsigned Size, unsigned &MappingID) {
if (Size == 32)
- return &Mips::ValueMappings[Mips::GPRIdx];
+ return &Mips::ValueMappings[Mips::GPR32Idx];
MappingID = CustomMappingID;
return &Mips::ValueMappings[Mips::DPRIdx];
@@ -394,7 +398,12 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
using namespace TargetOpcode;
unsigned NumOperands = MI.getNumOperands();
- const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
+ const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPR32Idx];
+ unsigned GPRSize = getMaximumSize(Mips::GPRBRegBankID);
+ assert((GPRSize == 32 || GPRSize == 64) && "Unexpected GPR size");
+ const ValueMapping *GPRValueMapping =
+ (GPRSize == 32) ? &Mips::ValueMappings[Mips::GPR32Idx]
+ : &Mips::ValueMappings[Mips::GPR64Idx];
unsigned MappingID = DefaultMappingID;
// Check if LLT sizes match sizes of available register banks.
@@ -433,7 +442,7 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case G_VASTART:
case G_BSWAP:
case G_CTLZ:
- OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
+ OperandsMapping = GPRValueMapping;
break;
case G_ADD:
case G_SUB:
@@ -442,15 +451,15 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case G_SREM:
case G_UDIV:
case G_UREM:
- OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
+ OperandsMapping = GPRValueMapping;
if (Op0Size == 128)
OperandsMapping = getMSAMapping(MF);
break;
case G_STORE:
case G_LOAD: {
if (Op0Size == 128) {
- OperandsMapping = getOperandsMapping(
- {getMSAMapping(MF), &Mips::ValueMappings[Mips::GPRIdx]});
+ OperandsMapping =
+ getOperandsMapping({getMSAMapping(MF), GPRValueMapping});
break;
}
@@ -459,16 +468,16 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
if (isFloatingPoint_32or64(InstTy, Op0Size) ||
isAmbiguous_64(InstTy, Op0Size)) {
- OperandsMapping = getOperandsMapping(
- {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]});
+ OperandsMapping =
+ getOperandsMapping({getFprbMapping(Op0Size), GPRValueMapping});
+ } else if (InstTy == InstType::Integer) {
+ OperandsMapping = getOperandsMapping({GPRValueMapping, GPRValueMapping});
} else {
- assert((isInteger_32(InstTy, Op0Size) ||
- isAmbiguous_32(InstTy, Op0Size) ||
+ assert((isAmbiguous_32(InstTy, Op0Size) ||
isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
"Unexpected Inst type");
- OperandsMapping =
- getOperandsMapping({getGprbOrCustomMapping(Op0Size, MappingID),
- &Mips::ValueMappings[Mips::GPRIdx]});
+ OperandsMapping = getOperandsMapping(
+ {getGprbOrCustomMapping(Op0Size, MappingID), GPRValueMapping});
}
break;
@@ -485,7 +494,7 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping,
/*NumOperands=*/1);
}
- assert((isInteger_32(InstTy, Op0Size) ||
+ assert((isInteger_32(InstTy, Op0Size) || isInteger_64(InstTy, Op0Size) ||
isFloatingPoint_32or64(InstTy, Op0Size) ||
isAmbiguous_32or64(InstTy, Op0Size)) &&
"Unexpected Inst type");
@@ -496,21 +505,22 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case G_SELECT: {
if (!Op0Ty.isPointer())
InstTy = TI.determineInstType(&MI);
+
if (isFloatingPoint_32or64(InstTy, Op0Size) ||
isAmbiguous_64(InstTy, Op0Size)) {
const RegisterBankInfo::ValueMapping *Bank = getFprbMapping(Op0Size);
- OperandsMapping = getOperandsMapping(
- {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
+ OperandsMapping = getOperandsMapping({Bank, GPRValueMapping, Bank, Bank});
break;
+ } else if (InstTy == InstType::Integer) {
+ OperandsMapping = getOperandsMapping(
+ {GPRValueMapping, GPRValueMapping, GPRValueMapping, GPRValueMapping});
} else {
- assert((isInteger_32(InstTy, Op0Size) ||
- isAmbiguous_32(InstTy, Op0Size) ||
+ assert((isAmbiguous_32(InstTy, Op0Size) ||
isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
"Unexpected Inst type");
const RegisterBankInfo::ValueMapping *Bank =
getGprbOrCustomMapping(Op0Size, MappingID);
- OperandsMapping = getOperandsMapping(
- {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
+ OperandsMapping = getOperandsMapping({Bank, GPRValueMapping, Bank, Bank});
}
break;
}
@@ -520,9 +530,10 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
if (isFloatingPoint_32or64(InstTy, Op0Size))
OperandsMapping = getFprbMapping(Op0Size);
- else {
- assert((isInteger_32(InstTy, Op0Size) ||
- isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
+ else if (InstTy == InstType::Integer) {
+ OperandsMapping = GPRValueMapping;
+ } else {
+ assert(isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) &&
"Unexpected Inst type");
OperandsMapping = getGprbOrCustomMapping(Op0Size, MappingID);
}
@@ -534,9 +545,8 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size) ||
isFloatingPoint_64(InstTy, Op3Size)) &&
"Unexpected Inst type");
- OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx],
- &Mips::ValueMappings[Mips::GPRIdx],
- &Mips::ValueMappings[Mips::DPRIdx]});
+ OperandsMapping = getOperandsMapping(
+ {GPRValueMapping, GPRValueMapping, &Mips::ValueMappings[Mips::DPRIdx]});
if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size))
MappingID = CustomMappingID;
break;
@@ -546,9 +556,8 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) ||
isFloatingPoint_64(InstTy, Op0Size)) &&
"Unexpected Inst type");
- OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx],
- &Mips::ValueMappings[Mips::GPRIdx],
- &Mips::ValueMappings[Mips::GPRIdx]});
+ OperandsMapping = getOperandsMapping(
+ {&Mips::ValueMappings[Mips::DPRIdx], GPRValueMapping, GPRValueMapping});
if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size))
MappingID = CustomMappingID;
break;
@@ -569,8 +578,8 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case G_FCMP: {
unsigned Op2Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
OperandsMapping =
- getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
- getFprbMapping(Op2Size), getFprbMapping(Op2Size)});
+ getOperandsMapping({GPRValueMapping, nullptr, getFprbMapping(Op2Size),
+ getFprbMapping(Op2Size)});
break;
}
case G_FPEXT:
@@ -582,36 +591,29 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
&Mips::ValueMappings[Mips::DPRIdx]});
break;
case G_FPTOSI: {
- assert((Op0Size == 32) && "Unsupported integer size");
unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
- OperandsMapping = getOperandsMapping(
- {&Mips::ValueMappings[Mips::GPRIdx], getFprbMapping(SizeFP)});
+ OperandsMapping =
+ getOperandsMapping({GPRValueMapping, getFprbMapping(SizeFP)});
break;
}
case G_SITOFP:
- assert((MRI.getType(MI.getOperand(1).getReg()).getSizeInBits() == 32) &&
- "Unsupported integer size");
- OperandsMapping = getOperandsMapping(
- {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]});
+ OperandsMapping =
+ getOperandsMapping({getFprbMapping(Op0Size), GPRValueMapping});
break;
case G_CONSTANT:
case G_FRAME_INDEX:
case G_GLOBAL_VALUE:
case G_JUMP_TABLE:
case G_BRCOND:
- OperandsMapping =
- getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr});
+ OperandsMapping = getOperandsMapping({GPRValueMapping, nullptr});
break;
case G_BRJT:
OperandsMapping =
- getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
- &Mips::ValueMappings[Mips::GPRIdx]});
+ getOperandsMapping({GPRValueMapping, nullptr, GPRValueMapping});
break;
case G_ICMP:
- OperandsMapping =
- getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
- &Mips::ValueMappings[Mips::GPRIdx],
- &Mips::ValueMappings[Mips::GPRIdx]});
+ OperandsMapping = getOperandsMapping(
+ {GPRValueMapping, nullptr, GPRValueMapping, GPRValueMapping});
break;
default:
return getInvalidInstructionMapping();
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.h b/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
index 1e07962fd02b3..220148b53452b 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
@@ -113,6 +113,12 @@ class MipsRegisterBankInfo final : public MipsGenRegisterBankInfo {
return false;
}
+ bool isInteger_64(InstType InstTy, unsigned OpSize) const {
+ if (InstTy == InstType::Integer && OpSize == 64)
+ return true;
+ return false;
+ }
+
/// Some generic instructions have operands that can be mapped to either fprb
/// or gprb e.g. for G_LOAD we consider only operand 0 as ambiguous, operand 1
/// is always gprb since it is a pointer.
diff --git a/llvm/lib/Target/Mips/MipsRegisterBanks.td b/llvm/lib/Target/Mips/MipsRegisterBanks.td
index 7d11475884cef..f5096d7539f92 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBanks.td
+++ b/llvm/lib/Target/Mips/MipsRegisterBanks.td
@@ -9,6 +9,6 @@
//
//===----------------------------------------------------------------------===//
-def GPRBRegBank : RegisterBank<"GPRB", [GPR32]>;
+def GPRBRegBank : RegisterBank<"GPRB", [GPR32, GPR64]>;
def FPRBRegBank : RegisterBank<"FPRB", [FGR64, AFGR64, MSA128D]>;
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/implicit_def_mips64.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/implicit_def_mips64.ll
new file mode 100644
index 0000000000000..2c51b5b99069b
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/implicit_def_mips64.ll
@@ -0,0 +1,13 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -O0 -mtriple=mips64el-linux-gnuabi64 -global-isel -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=MIPS64
+
+define i64 @func() {
+; MIPS64-LABEL: func:
+; MIPS64: # %bb.0: # %entry
+; MIPS64-NEXT: # implicit-def: $v0_64
+; MIPS64-NEXT: jr $ra
+; MIPS64-NEXT: nop
+entry:
+ ret i64 undef
+}
+
More information about the llvm-commits
mailing list