[llvm] [Mips] Fix $gp was restored when used as global register variable (PR #184975)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 6 01:56:13 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-mips
Author: None (yingopq)
<details>
<summary>Changes</summary>
The function `eliminateDeadMI` would check `if (MRI.isReserved(Reg))`, now we only set GP to reserved when `!Subtarget.isABICalls()`. So `eliminateDeadMI` delete the `move $gp, $4`. And we would restore $gp after instr selection through `$gp_64 = LD $sp_64, 8`.
Add a bool val when process instr `write_register` selection to represent whether $gp used as global register val. Then append new conditon when set $gp to reserverd status and return CalleeSavedRegs without $gp.
---
Full diff: https://github.com/llvm/llvm-project/pull/184975.diff
5 Files Affected:
- (modified) llvm/lib/Target/Mips/MipsCallingConv.td (+13)
- (modified) llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp (+10)
- (modified) llvm/lib/Target/Mips/MipsMachineFunction.h (+5)
- (modified) llvm/lib/Target/Mips/MipsRegisterInfo.cpp (+10-5)
- (added) llvm/test/CodeGen/Mips/write_register_gp.ll (+18)
``````````diff
diff --git a/llvm/lib/Target/Mips/MipsCallingConv.td b/llvm/lib/Target/Mips/MipsCallingConv.td
index 748162525b091..d3e552bc71ca9 100644
--- a/llvm/lib/Target/Mips/MipsCallingConv.td
+++ b/llvm/lib/Target/Mips/MipsCallingConv.td
@@ -362,16 +362,29 @@ def CSR_O32_FP64 :
def CSR_N32 : CalleeSavedRegs<(add(decimate(sequence "D%u_64", 30, 20), 2),
RA_64, FP_64, GP_64, (sequence "S%u_64", 7, 0))>;
+def CSR_N32_NoGP : CalleeSavedRegs<(add(decimate(sequence "D%u_64", 30, 20), 2),
+ RA_64, FP_64, (sequence "S%u_64", 7, 0))>;
+
def CSR_N32_SingleFloat
: CalleeSavedRegs<(add(decimate(sequence "F%u", 30, 20), 2), RA_64, FP_64,
GP_64, (sequence "S%u_64", 7, 0))>;
+def CSR_N32_SingleFloat_NoGP
+ : CalleeSavedRegs<(add(decimate(sequence "F%u", 30, 20), 2), RA_64, FP_64,
+ (sequence "S%u_64", 7, 0))>;
+
def CSR_N64 : CalleeSavedRegs<(add (sequence "D%u_64", 31, 24), RA_64, FP_64,
GP_64, (sequence "S%u_64", 7, 0))>;
+def CSR_N64_NoGP : CalleeSavedRegs<(add (sequence "D%u_64", 31, 24), RA_64, FP_64,
+ (sequence "S%u_64", 7, 0))>;
+
def CSR_N64_SingleFloat : CalleeSavedRegs<(add(sequence "F%u", 31, 24), RA_64,
FP_64, GP_64, (sequence "S%u_64", 7, 0))>;
+def CSR_N64_SingleFloat_NoGP : CalleeSavedRegs<(add(sequence "F%u", 31, 24), RA_64,
+ FP_64, (sequence "S%u_64", 7, 0))>;
+
def CSR_Mips16RetHelper :
CalleeSavedRegs<(add V0, V1, FP,
(sequence "A%u", 3, 0), (sequence "S%u", 7, 0),
diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
index 36706243232c0..41345de1f0cd9 100644
--- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -254,6 +254,16 @@ void MipsDAGToDAGISel::Select(SDNode *Node) {
ReplaceNode(Node, getGlobalBaseReg());
return;
+ case ISD::WRITE_REGISTER: {
+ MDNodeSDNode *MD = cast<MDNodeSDNode>(Node->getOperand(1));
+ const MDString *RegStr = cast<MDString>(MD->getMD()->getOperand(0));
+ StringRef Reg = RegStr->getString();
+ if (Reg == "$gp" || Reg == "$28" || Reg == "$28_64" || Reg == "$gp_64") {
+ MachineFunction &MF = CurDAG->getMachineFunction();
+ MF.getInfo<MipsFunctionInfo>()->setGPGlobalRegister(true);
+ }
+ break;
+ }
#ifndef NDEBUG
case ISD::LOAD:
case ISD::STORE:
diff --git a/llvm/lib/Target/Mips/MipsMachineFunction.h b/llvm/lib/Target/Mips/MipsMachineFunction.h
index b7b748838569f..cff249e8d9ba8 100644
--- a/llvm/lib/Target/Mips/MipsMachineFunction.h
+++ b/llvm/lib/Target/Mips/MipsMachineFunction.h
@@ -62,6 +62,9 @@ class MipsFunctionInfo : public MachineFunctionInfo {
int getEhDataRegFI(unsigned Reg) const { return EhDataRegFI[Reg]; }
bool isEhDataRegFI(int FI) const;
+ void setGPGlobalRegister(bool Val) { GPIsGlobalRegister = Val; }
+ bool isGPGlobalRegister() const { return GPIsGlobalRegister; }
+
/// Create a MachinePointerInfo that has an ExternalSymbolPseudoSourceValue
/// object representing a GOT entry for an external function.
MachinePointerInfo callPtrInfo(MachineFunction &MF, const char *ES);
@@ -126,6 +129,8 @@ class MipsFunctionInfo : public MachineFunctionInfo {
/// FrameIndex for expanding BuildPairF64 nodes to spill and reload when the
/// O32 FPXX ABI is enabled. -1 is used to denote invalid index.
int MoveF64ViaSpillFI = -1;
+
+ bool GPIsGlobalRegister = false;
};
} // end namespace llvm
diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
index 948d4db8585db..16fafcffdaa68 100644
--- a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -89,20 +89,23 @@ MipsRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
: CSR_Interrupt_32_SaveList;
}
+ bool GPIsGlobal = MF->getInfo<MipsFunctionInfo>()->isGPGlobalRegister();
// N64 ABI
if (Subtarget.isABI_N64()) {
if (Subtarget.isSingleFloat())
- return CSR_N64_SingleFloat_SaveList;
+ return GPIsGlobal ? CSR_N64_SingleFloat_NoGP_SaveList
+ : CSR_N64_SingleFloat_SaveList;
- return CSR_N64_SaveList;
+ return GPIsGlobal ? CSR_N64_NoGP_SaveList : CSR_N64_SaveList;
}
// N32 ABI
if (Subtarget.isABI_N32()) {
if (Subtarget.isSingleFloat())
- return CSR_N32_SingleFloat_SaveList;
+ return GPIsGlobal ? CSR_N32_SingleFloat_NoGP_SaveList
+ : CSR_N32_SingleFloat_SaveList;
- return CSR_N32_SaveList;
+ return GPIsGlobal ? CSR_N32_NoGP_SaveList : CSR_N32_SaveList;
}
// O32 ABI
@@ -122,6 +125,7 @@ const uint32_t *
MipsRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID) const {
const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
+
// N64 ABI
if (Subtarget.isABI_N64()) {
if (Subtarget.isSingleFloat())
@@ -175,7 +179,8 @@ getReservedRegs(const MachineFunction &MF) const {
Reserved.set(R);
// For mno-abicalls, GP is a program invariant!
- if (!Subtarget.isABICalls()) {
+ bool GPIsGlobal = MF.getInfo<MipsFunctionInfo>()->isGPGlobalRegister();
+ if (!Subtarget.isABICalls() || GPIsGlobal) {
Reserved.set(Mips::GP);
Reserved.set(Mips::GP_64);
}
diff --git a/llvm/test/CodeGen/Mips/write_register_gp.ll b/llvm/test/CodeGen/Mips/write_register_gp.ll
new file mode 100644
index 0000000000000..02b434126af81
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/write_register_gp.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple=mips64el -mcpu=mips64r2 < %s | FileCheck %s -check-prefix=MIPS64
+
+define void @setglobal(i64 %x) {
+; MIPS64-LABEL: setglobal:
+; MIPS64: # %bb.0: # %entry
+; MIPS64-NEXT: jr $ra
+; MIPS64-NEXT: move $gp, $4
+
+entry:
+ tail call void @llvm.write_register.i64(metadata !0, i64 %x)
+ ret void
+}
+
+declare void @llvm.write_register.i64(metadata, i64) #1
+
+!llvm.named.register.$28 = !{!0}
+!0 = !{!"$28"}
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/184975
More information about the llvm-commits
mailing list