Skip to content

Commit e49103b

Browse files
committed
[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 #63608. Differential Revision: https://reviews.llvm.org/D154445
1 parent 0f10850 commit e49103b

File tree

3 files changed

+1907
-185
lines changed

3 files changed

+1907
-185
lines changed

llvm/lib/Target/Mips/MipsISelLowering.cpp

+20-12
Original file line numberDiff line numberDiff line change
@@ -102,29 +102,37 @@ MVT MipsTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
102102
if (!VT.isVector())
103103
return getRegisterType(Context, VT);
104104

105-
return Subtarget.isABI_O32() || VT.getSizeInBits() == 32 ? MVT::i32
106-
: MVT::i64;
105+
if (VT.isPow2VectorType() && VT.getVectorElementType().isRound())
106+
return Subtarget.isABI_O32() || VT.getSizeInBits() == 32 ? MVT::i32
107+
: MVT::i64;
108+
return getRegisterType(Context, VT.getVectorElementType());
107109
}
108110

109111
unsigned MipsTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context,
110112
CallingConv::ID CC,
111113
EVT VT) const {
112-
if (VT.isVector())
113-
return divideCeil(VT.getSizeInBits(), Subtarget.isABI_O32() ? 32 : 64);
114+
if (VT.isVector()) {
115+
if (VT.isPow2VectorType() && VT.getVectorElementType().isRound())
116+
return divideCeil(VT.getSizeInBits(), Subtarget.isABI_O32() ? 32 : 64);
117+
return VT.getVectorNumElements() *
118+
getNumRegisters(Context, VT.getVectorElementType());
119+
}
114120
return MipsTargetLowering::getNumRegisters(Context, VT);
115121
}
116122

117123
unsigned MipsTargetLowering::getVectorTypeBreakdownForCallingConv(
118124
LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
119125
unsigned &NumIntermediates, MVT &RegisterVT) const {
120-
// Break down vector types to either 2 i64s or 4 i32s.
121-
RegisterVT = getRegisterTypeForCallingConv(Context, CC, VT);
122-
IntermediateVT = RegisterVT;
123-
NumIntermediates =
124-
VT.getFixedSizeInBits() < RegisterVT.getFixedSizeInBits()
125-
? VT.getVectorNumElements()
126-
: divideCeil(VT.getSizeInBits(), RegisterVT.getSizeInBits());
127-
return NumIntermediates;
126+
if (VT.isPow2VectorType()) {
127+
IntermediateVT = getRegisterTypeForCallingConv(Context, CC, VT);
128+
RegisterVT = IntermediateVT.getSimpleVT();
129+
NumIntermediates = getNumRegistersForCallingConv(Context, CC, VT);
130+
return NumIntermediates;
131+
}
132+
IntermediateVT = VT.getVectorElementType();
133+
NumIntermediates = VT.getVectorNumElements();
134+
RegisterVT = getRegisterType(Context, IntermediateVT);
135+
return NumIntermediates * getNumRegisters(Context, IntermediateVT);
128136
}
129137

130138
SDValue MipsTargetLowering::getGlobalReg(SelectionDAG &DAG, EVT Ty) const {

0 commit comments

Comments
 (0)