Skip to content

Commit 3803552

Browse files
nikicarichardson
authored andcommitted
[Mips] Fix argument lowering for illegal vector types (PR63608)
The Mips MSA ABI requires that legal vector types are passed in scalar registers in packed representation. E.g. a type like v16i8 would be passed as two i64 registers. The implementation attempts to do the same for illegal vectors with non-power-of-two element counts or non-power-of-two element types. However, the SDAG argument lowering code doesn't support this, and it is not easy to extend it to support this (we would have to deal with situations like passing v7i18 as two i64 values). This patch instead opts to restrict the special argument lowering to only vectors with power-of-two elements and round element types. Everything else is lowered naively, that is by passing each element in promoted registers. Fixes llvm/llvm-project#63608. Differential Revision: https://reviews.llvm.org/D154445
2 parents f51d306 + e49103b commit 3803552

File tree

3 files changed

+1907
-185
lines changed

3 files changed

+1907
-185
lines changed

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,29 +128,37 @@ MVT MipsTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
128128
if (!VT.isVector())
129129
return getRegisterType(Context, VT);
130130

131-
return Subtarget.isABI_O32() || VT.getSizeInBits() == 32 ? MVT::i32
132-
: MVT::i64;
131+
if (VT.isPow2VectorType() && VT.getVectorElementType().isRound())
132+
return Subtarget.isABI_O32() || VT.getSizeInBits() == 32 ? MVT::i32
133+
: MVT::i64;
134+
return getRegisterType(Context, VT.getVectorElementType());
133135
}
134136

135137
unsigned MipsTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context,
136138
CallingConv::ID CC,
137139
EVT VT) const {
138-
if (VT.isVector())
139-
return divideCeil(VT.getSizeInBits(), Subtarget.isABI_O32() ? 32 : 64);
140+
if (VT.isVector()) {
141+
if (VT.isPow2VectorType() && VT.getVectorElementType().isRound())
142+
return divideCeil(VT.getSizeInBits(), Subtarget.isABI_O32() ? 32 : 64);
143+
return VT.getVectorNumElements() *
144+
getNumRegisters(Context, VT.getVectorElementType());
145+
}
140146
return MipsTargetLowering::getNumRegisters(Context, VT);
141147
}
142148

143149
unsigned MipsTargetLowering::getVectorTypeBreakdownForCallingConv(
144150
LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
145151
unsigned &NumIntermediates, MVT &RegisterVT) const {
146-
// Break down vector types to either 2 i64s or 4 i32s.
147-
RegisterVT = getRegisterTypeForCallingConv(Context, CC, VT);
148-
IntermediateVT = RegisterVT;
149-
NumIntermediates =
150-
VT.getFixedSizeInBits() < RegisterVT.getFixedSizeInBits()
151-
? VT.getVectorNumElements()
152-
: divideCeil(VT.getSizeInBits(), RegisterVT.getSizeInBits());
153-
return NumIntermediates;
152+
if (VT.isPow2VectorType()) {
153+
IntermediateVT = getRegisterTypeForCallingConv(Context, CC, VT);
154+
RegisterVT = IntermediateVT.getSimpleVT();
155+
NumIntermediates = getNumRegistersForCallingConv(Context, CC, VT);
156+
return NumIntermediates;
157+
}
158+
IntermediateVT = VT.getVectorElementType();
159+
NumIntermediates = VT.getVectorNumElements();
160+
RegisterVT = getRegisterType(Context, IntermediateVT);
161+
return NumIntermediates * getNumRegisters(Context, IntermediateVT);
154162
}
155163

156164
SDValue MipsTargetLowering::getGlobalReg(SelectionDAG &DAG, EVT Ty,

0 commit comments

Comments
 (0)