Skip to content

Commit 0960960

Browse files
committed
[Mips] Fix clang crashes when compiling a variadic function while targeting mips3
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`. When process `CC_Mips_FixedArg`, mips would CCDelegateTo `CC_MipsO32_FP`. In fact, it should CCDelegateTo `CC_MipsN`. Fix #98716.
1 parent 557628d commit 0960960

File tree

6 files changed

+65
-8
lines changed

6 files changed

+65
-8
lines changed

llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,13 @@ ArrayRef<MCPhysReg> MipsABIInfo::GetByValArgRegs() const {
3737
llvm_unreachable("Unhandled ABI");
3838
}
3939

40-
ArrayRef<MCPhysReg> MipsABIInfo::GetVarArgRegs() const {
41-
if (IsO32())
42-
return ArrayRef(O32IntRegs);
40+
ArrayRef<MCPhysReg> MipsABIInfo::GetVarArgRegs(bool isGP64bit) const {
41+
if (IsO32()) {
42+
if (isGP64bit)
43+
return ArrayRef(Mips64IntRegs);
44+
else
45+
return ArrayRef(O32IntRegs);
46+
}
4347
if (IsN32() || IsN64())
4448
return ArrayRef(Mips64IntRegs);
4549
llvm_unreachable("Unhandled ABI");

llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class MipsABIInfo {
4646
ArrayRef<MCPhysReg> GetByValArgRegs() const;
4747

4848
/// The registers to use for the variable argument list.
49-
ArrayRef<MCPhysReg> GetVarArgRegs() const;
49+
ArrayRef<MCPhysReg> GetVarArgRegs(bool isGP64bit) const;
5050

5151
/// Obtain the size of the area allocated by the callee for arguments.
5252
/// CallingConv::FastCall affects the value for O32.

llvm/lib/Target/Mips/MipsCallLowering.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,8 @@ bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
406406
return false;
407407

408408
if (F.isVarArg()) {
409-
ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs();
409+
ArrayRef<MCPhysReg> ArgRegs =
410+
ABI.GetVarArgRegs(MF.getSubtarget<MipsSubtarget>().isGP64bit());
410411
unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
411412

412413
int VaArgOffset;

llvm/lib/Target/Mips/MipsCallingConv.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ def CC_Mips_FixedArg : CallingConv<[
339339

340340
CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_Mips_FastCC>>,
341341

342-
CCIfSubtarget<"isABI_O32()", CCDelegateTo<CC_MipsO32_FP>>,
342+
CCIfSubtarget<"isABI_O32()", CCIfSubtargetNot<"isGP64bit()", CCDelegateTo<CC_MipsO32_FP>>>,
343343
CCDelegateTo<CC_MipsN>
344344
]>;
345345

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3400,7 +3400,6 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
34003400
SDValue StackPtr =
34013401
DAG.getCopyFromReg(Chain, DL, ABI.IsN64() ? Mips::SP_64 : Mips::SP,
34023402
getPointerTy(DAG.getDataLayout()));
3403-
34043403
std::deque<std::pair<unsigned, SDValue>> RegsToPass;
34053404
SmallVector<SDValue, 8> MemOpChains;
34063405

@@ -4640,7 +4639,7 @@ void MipsTargetLowering::writeVarArgRegs(std::vector<SDValue> &OutChains,
46404639
SDValue Chain, const SDLoc &DL,
46414640
SelectionDAG &DAG,
46424641
CCState &State) const {
4643-
ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs();
4642+
ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs(Subtarget.isGP64bit());
46444643
unsigned Idx = State.getFirstUnallocated(ArgRegs);
46454644
unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();
46464645
MVT RegTy = MVT::getIntegerVT(RegSizeInBytes * 8);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips3 -target-abi o32 < %s | FileCheck %s -check-prefixes=MIPS3-O32
2+
; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips3 -target-abi n32 < %s | FileCheck %s -check-prefixes=MIPS3-N32
3+
; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips3 -target-abi n64 < %s | FileCheck %s -check-prefixes=MIPS3-N64
4+
5+
define void @func(ptr noundef %x, ...) nounwind {
6+
; MIPS3-O32-LABEL: func:
7+
; MIPS32-O32: # %bb.0: # %entry
8+
; MIPS32-O32-NEXT: addiu $sp, $sp, -48
9+
; MIPS32-O32-NEXT: sd $11, 56($sp)
10+
; MIPS32-O32-NEXT: sd $10, 48($sp)
11+
; MIPS32-O32-NEXT: sd $9, 40($sp)
12+
; MIPS32-O32-NEXT: sd $8, 32($sp)
13+
; MIPS32-O32-NEXT: sd $7, 24($sp)
14+
; MIPS32-O32-NEXT: sd $6, 16($sp)
15+
; MIPS32-O32-NEXT: sd $5, 8($sp)
16+
; MIPS32-O32-NEXT: sw $4, 4($sp)
17+
; MIPS32-O32-NEXT: jr $ra
18+
; MIPS32-O32-NEXT: addiu $sp, $sp, 48
19+
;
20+
; MIPS3-N32-LABEL: func:
21+
; MIPS32-N32: # %bb.0: # %entry
22+
; MIPS32-N32-NEXT: addiu $sp, $sp, -64
23+
; MIPS32-N32-NEXT: sd $11, 56($sp)
24+
; MIPS32-N32-NEXT: sd $10, 48($sp)
25+
; MIPS32-N32-NEXT: sd $9, 40($sp)
26+
; MIPS32-N32-NEXT: sd $8, 32($sp)
27+
; MIPS32-N32-NEXT: sd $7, 24($sp)
28+
; MIPS32-N32-NEXT: sd $6, 16($sp)
29+
; MIPS32-N32-NEXT: sd $5, 8($sp)
30+
; MIPS32-N32-NEXT: sw $4, 4($sp)
31+
; MIPS32-N32-NEXT: jr $ra
32+
; MIPS32-N32-NEXT: addiu $sp, $sp, 64
33+
;
34+
; MIPS3-N64-LABEL: func:
35+
; MIPS32-N64: # %bb.0: # %entry
36+
; MIPS32-N64-NEXT: addiu $sp, $sp, -64
37+
; MIPS32-N64-NEXT: sdl $4, 7($sp)
38+
; MIPS32-N64-NEXT: sd $11, 56($sp)
39+
; MIPS32-N64-NEXT: sd $10, 48($sp)
40+
; MIPS32-N64-NEXT: sd $9, 40($sp)
41+
; MIPS32-N64-NEXT: sd $8, 32($sp)
42+
; MIPS32-N64-NEXT: sd $7, 24($sp)
43+
; MIPS32-N64-NEXT: sd $6, 16($sp)
44+
; MIPS32-N64-NEXT: sd $5, 8($sp)
45+
; MIPS32-N64-NEXT: sw $4, 4($sp)
46+
; MIPS32-N64-NEXT: jr $ra
47+
; MIPS32-N64-NEXT: addiu $sp, $sp, 64
48+
49+
entry:
50+
%x.addr = alloca ptr, align 4
51+
store ptr %x, ptr %x.addr, align 4
52+
ret void
53+
}

0 commit comments

Comments
 (0)