Skip to content

Commit 3a4b0e9

Browse files
authored
[RISCV][GISel] Disable call lowering for integers larger than 2*XLen. (#69144)
Types larger than 2*XLen are passed indirectly which is not supported yet. Currently, we will incorrectly pass X10 multiple times.
1 parent 734b016 commit 3a4b0e9

File tree

1 file changed

+48
-18
lines changed

1 file changed

+48
-18
lines changed

llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -193,15 +193,52 @@ struct RISCVCallReturnHandler : public RISCVIncomingValueHandler {
193193
RISCVCallLowering::RISCVCallLowering(const RISCVTargetLowering &TLI)
194194
: CallLowering(&TLI) {}
195195

196+
// TODO: Support all argument types.
197+
static bool isSupportedArgumentType(Type *T, const RISCVSubtarget &Subtarget) {
198+
// TODO: Integers larger than 2*XLen are passed indirectly which is not
199+
// supported yet.
200+
if (T->isIntegerTy())
201+
return T->getIntegerBitWidth() <= Subtarget.getXLen() * 2;
202+
if (T->isPointerTy())
203+
return true;
204+
return false;
205+
}
206+
207+
// TODO: Only integer, pointer and aggregate types are supported now.
208+
static bool isSupportedReturnType(Type *T, const RISCVSubtarget &Subtarget) {
209+
// TODO: Integers larger than 2*XLen are passed indirectly which is not
210+
// supported yet.
211+
if (T->isIntegerTy())
212+
return T->getIntegerBitWidth() <= Subtarget.getXLen() * 2;
213+
if (T->isPointerTy())
214+
return true;
215+
216+
if (T->isArrayTy())
217+
return isSupportedReturnType(T->getArrayElementType(), Subtarget);
218+
219+
if (T->isStructTy()) {
220+
// For now we only allow homogeneous structs that we can manipulate with
221+
// G_MERGE_VALUES and G_UNMERGE_VALUES
222+
auto StructT = cast<StructType>(T);
223+
for (unsigned i = 1, e = StructT->getNumElements(); i != e; ++i)
224+
if (StructT->getElementType(i) != StructT->getElementType(0))
225+
return false;
226+
return isSupportedReturnType(StructT->getElementType(0), Subtarget);
227+
}
228+
229+
return false;
230+
}
231+
196232
bool RISCVCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
197233
const Value *Val,
198234
ArrayRef<Register> VRegs,
199235
MachineInstrBuilder &Ret) const {
200236
if (!Val)
201237
return true;
202238

203-
// TODO: Only integer, pointer and aggregate types are supported now.
204-
if (!Val->getType()->isIntOrPtrTy() && !Val->getType()->isAggregateType())
239+
const RISCVSubtarget &Subtarget =
240+
MIRBuilder.getMF().getSubtarget<RISCVSubtarget>();
241+
if (!isSupportedReturnType(Val->getType(), Subtarget))
205242
return false;
206243

207244
MachineFunction &MF = MIRBuilder.getMF();
@@ -248,13 +285,11 @@ bool RISCVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
248285
if (F.isVarArg())
249286
return false;
250287

251-
// TODO: Support all argument types.
288+
const RISCVSubtarget &Subtarget =
289+
MIRBuilder.getMF().getSubtarget<RISCVSubtarget>();
252290
for (auto &Arg : F.args()) {
253-
if (Arg.getType()->isIntegerTy())
254-
continue;
255-
if (Arg.getType()->isPointerTy())
256-
continue;
257-
return false;
291+
if (!isSupportedArgumentType(Arg.getType(), Subtarget))
292+
return false;
258293
}
259294

260295
MachineFunction &MF = MIRBuilder.getMF();
@@ -292,15 +327,11 @@ bool RISCVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
292327
const Function &F = MF.getFunction();
293328
CallingConv::ID CC = F.getCallingConv();
294329

295-
// TODO: Support all argument types.
330+
const RISCVSubtarget &Subtarget =
331+
MIRBuilder.getMF().getSubtarget<RISCVSubtarget>();
296332
for (auto &AInfo : Info.OrigArgs) {
297-
if (AInfo.Ty->isIntegerTy())
298-
continue;
299-
if (AInfo.Ty->isPointerTy())
300-
continue;
301-
if (AInfo.Ty->isFloatingPointTy())
302-
continue;
303-
return false;
333+
if (!isSupportedArgumentType(AInfo.Ty, Subtarget))
334+
return false;
304335
}
305336

306337
SmallVector<ArgInfo, 32> SplitArgInfos;
@@ -337,8 +368,7 @@ bool RISCVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
337368
if (Info.OrigRet.Ty->isVoidTy())
338369
return true;
339370

340-
// TODO: Only integer, pointer and aggregate types are supported now.
341-
if (!Info.OrigRet.Ty->isIntOrPtrTy() && !Info.OrigRet.Ty->isAggregateType())
371+
if (!isSupportedReturnType(Info.OrigRet.Ty, Subtarget))
342372
return false;
343373

344374
SmallVector<ArgInfo, 4> SplitRetInfos;

0 commit comments

Comments
 (0)