diff --git a/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp b/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp index 215aa938e5dc4..aeb7f96c3f9ba 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp @@ -193,6 +193,42 @@ struct RISCVCallReturnHandler : public RISCVIncomingValueHandler { RISCVCallLowering::RISCVCallLowering(const RISCVTargetLowering &TLI) : CallLowering(&TLI) {} +// TODO: Support all argument types. +static bool isSupportedArgumentType(Type *T, const RISCVSubtarget &Subtarget) { + // TODO: Integers larger than 2*XLen are passed indirectly which is not + // supported yet. + if (T->isIntegerTy()) + return T->getIntegerBitWidth() <= Subtarget.getXLen() * 2; + if (T->isPointerTy()) + return true; + return false; +} + +// TODO: Only integer, pointer and aggregate types are supported now. +static bool isSupportedReturnType(Type *T, const RISCVSubtarget &Subtarget) { + // TODO: Integers larger than 2*XLen are passed indirectly which is not + // supported yet. + if (T->isIntegerTy()) + return T->getIntegerBitWidth() <= Subtarget.getXLen() * 2; + if (T->isPointerTy()) + return true; + + if (T->isArrayTy()) + return isSupportedReturnType(T->getArrayElementType(), Subtarget); + + if (T->isStructTy()) { + // For now we only allow homogeneous structs that we can manipulate with + // G_MERGE_VALUES and G_UNMERGE_VALUES + auto StructT = cast(T); + for (unsigned i = 1, e = StructT->getNumElements(); i != e; ++i) + if (StructT->getElementType(i) != StructT->getElementType(0)) + return false; + return isSupportedReturnType(StructT->getElementType(0), Subtarget); + } + + return false; +} + bool RISCVCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef VRegs, @@ -200,8 +236,9 @@ bool RISCVCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder, if (!Val) return true; - // TODO: Only integer, pointer and aggregate types are supported now. - if (!Val->getType()->isIntOrPtrTy() && !Val->getType()->isAggregateType()) + const RISCVSubtarget &Subtarget = + MIRBuilder.getMF().getSubtarget(); + if (!isSupportedReturnType(Val->getType(), Subtarget)) return false; MachineFunction &MF = MIRBuilder.getMF(); @@ -248,13 +285,11 @@ bool RISCVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, if (F.isVarArg()) return false; - // TODO: Support all argument types. + const RISCVSubtarget &Subtarget = + MIRBuilder.getMF().getSubtarget(); for (auto &Arg : F.args()) { - if (Arg.getType()->isIntegerTy()) - continue; - if (Arg.getType()->isPointerTy()) - continue; - return false; + if (!isSupportedArgumentType(Arg.getType(), Subtarget)) + return false; } MachineFunction &MF = MIRBuilder.getMF(); @@ -292,15 +327,11 @@ bool RISCVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const Function &F = MF.getFunction(); CallingConv::ID CC = F.getCallingConv(); - // TODO: Support all argument types. + const RISCVSubtarget &Subtarget = + MIRBuilder.getMF().getSubtarget(); for (auto &AInfo : Info.OrigArgs) { - if (AInfo.Ty->isIntegerTy()) - continue; - if (AInfo.Ty->isPointerTy()) - continue; - if (AInfo.Ty->isFloatingPointTy()) - continue; - return false; + if (!isSupportedArgumentType(AInfo.Ty, Subtarget)) + return false; } SmallVector SplitArgInfos; @@ -337,8 +368,7 @@ bool RISCVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, if (Info.OrigRet.Ty->isVoidTy()) return true; - // TODO: Only integer, pointer and aggregate types are supported now. - if (!Info.OrigRet.Ty->isIntOrPtrTy() && !Info.OrigRet.Ty->isAggregateType()) + if (!isSupportedReturnType(Info.OrigRet.Ty, Subtarget)) return false; SmallVector SplitRetInfos;