[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