Skip to content

Commit e676866

Browse files
authored
[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.
1 parent bed03ae commit e676866

File tree

6 files changed

+66
-8
lines changed

6 files changed

+66
-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

@@ -4654,7 +4653,7 @@ void MipsTargetLowering::writeVarArgRegs(std::vector<SDValue> &OutChains,
46544653
SDValue Chain, const SDLoc &DL,
46554654
SelectionDAG &DAG,
46564655
CCState &State) const {
4657-
ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs();
4656+
ArrayRef<MCPhysReg> ArgRegs = ABI.getVarArgRegs(Subtarget.isGP64bit());
46584657
unsigned Idx = State.getFirstUnallocated(ArgRegs);
46594658
unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();
46604659
MVT RegTy = MVT::getIntegerVT(RegSizeInBytes * 8);

llvm/test/CodeGen/Mips/vararg.ll

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips3 -target-abi o32 < %s | FileCheck %s -check-prefixes=MIPS3-O32
3+
; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips3 -target-abi n32 < %s | FileCheck %s -check-prefixes=MIPS3-N32
4+
; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips3 -target-abi n64 < %s | FileCheck %s -check-prefixes=MIPS3-N64
5+
6+
define void @func(ptr nocapture %x, ...) nounwind {
7+
; MIPS3-O32-LABEL: func:
8+
; MIPS32-O32: # %bb.0: # %entry
9+
; MIPS32-O32-NEXT: addiu $sp, $sp, -48
10+
; MIPS32-O32-NEXT: sd $11, 56($sp)
11+
; MIPS32-O32-NEXT: sd $10, 48($sp)
12+
; MIPS32-O32-NEXT: sd $9, 40($sp)
13+
; MIPS32-O32-NEXT: sd $8, 32($sp)
14+
; MIPS32-O32-NEXT: sd $7, 24($sp)
15+
; MIPS32-O32-NEXT: sd $6, 16($sp)
16+
; MIPS32-O32-NEXT: sd $5, 8($sp)
17+
; MIPS32-O32-NEXT: sw $4, 4($sp)
18+
; MIPS32-O32-NEXT: jr $ra
19+
; MIPS32-O32-NEXT: addiu $sp, $sp, 48
20+
;
21+
; MIPS3-N32-LABEL: func:
22+
; MIPS32-N32: # %bb.0: # %entry
23+
; MIPS32-N32-NEXT: addiu $sp, $sp, -64
24+
; MIPS32-N32-NEXT: sd $11, 56($sp)
25+
; MIPS32-N32-NEXT: sd $10, 48($sp)
26+
; MIPS32-N32-NEXT: sd $9, 40($sp)
27+
; MIPS32-N32-NEXT: sd $8, 32($sp)
28+
; MIPS32-N32-NEXT: sd $7, 24($sp)
29+
; MIPS32-N32-NEXT: sd $6, 16($sp)
30+
; MIPS32-N32-NEXT: sd $5, 8($sp)
31+
; MIPS32-N32-NEXT: sw $4, 4($sp)
32+
; MIPS32-N32-NEXT: jr $ra
33+
; MIPS32-N32-NEXT: addiu $sp, $sp, 64
34+
;
35+
; MIPS3-N64-LABEL: func:
36+
; MIPS32-N64: # %bb.0: # %entry
37+
; MIPS32-N64-NEXT: addiu $sp, $sp, -64
38+
; MIPS32-N64-NEXT: sdl $4, 7($sp)
39+
; MIPS32-N64-NEXT: sd $11, 56($sp)
40+
; MIPS32-N64-NEXT: sd $10, 48($sp)
41+
; MIPS32-N64-NEXT: sd $9, 40($sp)
42+
; MIPS32-N64-NEXT: sd $8, 32($sp)
43+
; MIPS32-N64-NEXT: sd $7, 24($sp)
44+
; MIPS32-N64-NEXT: sd $6, 16($sp)
45+
; MIPS32-N64-NEXT: sd $5, 8($sp)
46+
; MIPS32-N64-NEXT: sw $4, 4($sp)
47+
; MIPS32-N64-NEXT: jr $ra
48+
; MIPS32-N64-NEXT: addiu $sp, $sp, 64
49+
50+
entry:
51+
%x.addr = alloca ptr, align 4
52+
store ptr %x, ptr %x.addr, align 4
53+
ret void
54+
}

0 commit comments

Comments
 (0)