[llvm] e676866 - [Mips] Fix clang crashes when compiling a variadic function while targeting mips3 (#130558)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 15 19:56:10 PDT 2025


Author: yingopq
Date: 2025-04-16T10:56:06+08:00
New Revision: e676866368a84c88aad90e138268e00a1c56a230

URL: https://github.com/llvm/llvm-project/commit/e676866368a84c88aad90e138268e00a1c56a230
DIFF: https://github.com/llvm/llvm-project/commit/e676866368a84c88aad90e138268e00a1c56a230.diff

LOG: [Mips] Fix clang crashes when compiling a variadic function while targeting mips3 (#130558)

issue reason:
Because mips3 has the feature 'FeatureGP64Bit', when target mips3
process function `writeVarArgRegs`, the result of `getGPRSizeInBytes` is
8 and the result of `GetVarArgRegs` is `Mips::A0, Mips::A1, Mips::A2,
Mips::A3`. This would generate `gpr64 = COPY $a1` which should be `gpr64
= COPY $a1_64`.

Also when process `CC_Mips_FixedArg`, mips would CCDelegateTo
    `CC_MipsO32_FP`. In fact, it should CCDelegateTo `CC_MipsN`.

Fix #98716.

Added: 
    llvm/test/CodeGen/Mips/vararg.ll

Modified: 
    llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
    llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
    llvm/lib/Target/Mips/MipsCallLowering.cpp
    llvm/lib/Target/Mips/MipsCallingConv.td
    llvm/lib/Target/Mips/MipsISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
index 08cbba952ccc8..1be29cf3c94b9 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
@@ -37,9 +37,13 @@ ArrayRef<MCPhysReg> MipsABIInfo::GetByValArgRegs() const {
   llvm_unreachable("Unhandled ABI");
 }
 
-ArrayRef<MCPhysReg> MipsABIInfo::GetVarArgRegs() const {
-  if (IsO32())
-    return ArrayRef(O32IntRegs);
+ArrayRef<MCPhysReg> MipsABIInfo::getVarArgRegs(bool isGP64bit) const {
+  if (IsO32()) {
+    if (isGP64bit)
+      return ArrayRef(Mips64IntRegs);
+    else
+      return ArrayRef(O32IntRegs);
+  }
   if (IsN32() || IsN64())
     return ArrayRef(Mips64IntRegs);
   llvm_unreachable("Unhandled ABI");

diff  --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
index 41f80771142de..44b023c7c3ef6 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
@@ -46,7 +46,7 @@ class MipsABIInfo {
   ArrayRef<MCPhysReg> GetByValArgRegs() const;
 
   /// The registers to use for the variable argument list.
-  ArrayRef<MCPhysReg> GetVarArgRegs() const;
+  ArrayRef<MCPhysReg> getVarArgRegs(bool isGP64bit) const;
 
   /// Obtain the size of the area allocated by the callee for arguments.
   /// CallingConv::FastCall affects the value for O32.

diff  --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp
index b856290211277..01c9d0b38323e 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp
@@ -406,7 +406,8 @@ bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
     return false;
 
   if (F.isVarArg()) {
-    ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs();
+    ArrayRef<MCPhysReg> ArgRegs =
+        ABI.getVarArgRegs(MF.getSubtarget<MipsSubtarget>().isGP64bit());
     unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
 
     int VaArgOffset;

diff  --git a/llvm/lib/Target/Mips/MipsCallingConv.td b/llvm/lib/Target/Mips/MipsCallingConv.td
index 25384a3fe8de3..3c60114f507b9 100644
--- a/llvm/lib/Target/Mips/MipsCallingConv.td
+++ b/llvm/lib/Target/Mips/MipsCallingConv.td
@@ -339,7 +339,7 @@ def CC_Mips_FixedArg : CallingConv<[
 
   CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_Mips_FastCC>>,
 
-  CCIfSubtarget<"isABI_O32()", CCDelegateTo<CC_MipsO32_FP>>,
+  CCIfSubtarget<"isABI_O32()", CCIfSubtargetNot<"isGP64bit()", CCDelegateTo<CC_MipsO32_FP>>>,
   CCDelegateTo<CC_MipsN>
 ]>;
 

diff  --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index fa8a4704730cf..55fc636d3c781 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -3400,7 +3400,6 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
   SDValue StackPtr =
       DAG.getCopyFromReg(Chain, DL, ABI.IsN64() ? Mips::SP_64 : Mips::SP,
                          getPointerTy(DAG.getDataLayout()));
-
   std::deque<std::pair<unsigned, SDValue>> RegsToPass;
   SmallVector<SDValue, 8> MemOpChains;
 
@@ -4654,7 +4653,7 @@ void MipsTargetLowering::writeVarArgRegs(std::vector<SDValue> &OutChains,
                                          SDValue Chain, const SDLoc &DL,
                                          SelectionDAG &DAG,
                                          CCState &State) const {
-  ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs();
+  ArrayRef<MCPhysReg> ArgRegs = ABI.getVarArgRegs(Subtarget.isGP64bit());
   unsigned Idx = State.getFirstUnallocated(ArgRegs);
   unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();
   MVT RegTy = MVT::getIntegerVT(RegSizeInBytes * 8);

diff  --git a/llvm/test/CodeGen/Mips/vararg.ll b/llvm/test/CodeGen/Mips/vararg.ll
new file mode 100644
index 0000000000000..ed4a805af0c0c
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/vararg.ll
@@ -0,0 +1,54 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips3 -target-abi o32 < %s | FileCheck %s -check-prefixes=MIPS3-O32
+; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips3 -target-abi n32 < %s | FileCheck %s -check-prefixes=MIPS3-N32
+; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips3 -target-abi n64 < %s | FileCheck %s -check-prefixes=MIPS3-N64
+
+define void @func(ptr nocapture %x, ...) nounwind {
+; MIPS3-O32-LABEL: func:
+; MIPS32-O32:       # %bb.0: # %entry
+; MIPS32-O32-NEXT:    addiu $sp, $sp, -48
+; MIPS32-O32-NEXT:    sd $11, 56($sp)
+; MIPS32-O32-NEXT:    sd $10, 48($sp)
+; MIPS32-O32-NEXT:    sd $9, 40($sp)
+; MIPS32-O32-NEXT:    sd $8, 32($sp)
+; MIPS32-O32-NEXT:    sd $7, 24($sp)
+; MIPS32-O32-NEXT:    sd $6, 16($sp)
+; MIPS32-O32-NEXT:    sd $5, 8($sp)
+; MIPS32-O32-NEXT:    sw $4, 4($sp)
+; MIPS32-O32-NEXT:    jr $ra
+; MIPS32-O32-NEXT:    addiu $sp, $sp, 48
+;
+; MIPS3-N32-LABEL: func:
+; MIPS32-N32:       # %bb.0: # %entry
+; MIPS32-N32-NEXT:    addiu $sp, $sp, -64
+; MIPS32-N32-NEXT:    sd $11, 56($sp)
+; MIPS32-N32-NEXT:    sd $10, 48($sp)
+; MIPS32-N32-NEXT:    sd $9, 40($sp)
+; MIPS32-N32-NEXT:    sd $8, 32($sp)
+; MIPS32-N32-NEXT:    sd $7, 24($sp)
+; MIPS32-N32-NEXT:    sd $6, 16($sp)
+; MIPS32-N32-NEXT:    sd $5, 8($sp)
+; MIPS32-N32-NEXT:    sw $4, 4($sp)
+; MIPS32-N32-NEXT:    jr $ra
+; MIPS32-N32-NEXT:    addiu $sp, $sp, 64
+;
+; MIPS3-N64-LABEL: func:
+; MIPS32-N64:       # %bb.0: # %entry
+; MIPS32-N64-NEXT:    addiu $sp, $sp, -64
+; MIPS32-N64-NEXT:    sdl $4, 7($sp)
+; MIPS32-N64-NEXT:    sd $11, 56($sp)
+; MIPS32-N64-NEXT:    sd $10, 48($sp)
+; MIPS32-N64-NEXT:    sd $9, 40($sp)
+; MIPS32-N64-NEXT:    sd $8, 32($sp)
+; MIPS32-N64-NEXT:    sd $7, 24($sp)
+; MIPS32-N64-NEXT:    sd $6, 16($sp)
+; MIPS32-N64-NEXT:    sd $5, 8($sp)
+; MIPS32-N64-NEXT:    sw $4, 4($sp)
+; MIPS32-N64-NEXT:    jr $ra
+; MIPS32-N64-NEXT:    addiu $sp, $sp, 64
+
+entry:
+  %x.addr = alloca ptr, align 4
+  store ptr %x, ptr %x.addr, align 4
+  ret void
+}


        


More information about the llvm-commits mailing list