diff options
author | Brandon Wu <songwu0813@gmail.com> | 2025-08-20 16:39:02 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-20 16:39:02 +0800 |
commit | 52a2e68fda7b4adbcd677fe77ac9eb4c48039ec9 (patch) | |
tree | ac902228746cd34fbeb7d86f59892f6f04c94e69 /clang/lib/CodeGen/CGCall.cpp | |
parent | e16ced3ef411531377fe7f90df82286cf1eb980e (diff) | |
download | llvm-52a2e68fda7b4adbcd677fe77ac9eb4c48039ec9.zip llvm-52a2e68fda7b4adbcd677fe77ac9eb4c48039ec9.tar.gz llvm-52a2e68fda7b4adbcd677fe77ac9eb4c48039ec9.tar.bz2 |
[clang][RISCV] Fix crash on VLS calling convention (#145489)
This patch handle struct of fixed vector and struct of array of fixed
vector correctly for VLS calling convention in EmitFunctionProlog,
EmitFunctionEpilog and EmitCall.
stack on: https://github.com/llvm/llvm-project/pull/147173
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 71 |
1 files changed, 60 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index b959982..466546b 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1602,6 +1602,7 @@ void ClangToLLVMArgMapping::construct(const ASTContext &Context, IRArgs.PaddingArgIndex = IRArgNo++; switch (AI.getKind()) { + case ABIArgInfo::TargetSpecific: case ABIArgInfo::Extend: case ABIArgInfo::Direct: { // FIXME: handle sseregparm someday... @@ -1712,6 +1713,7 @@ llvm::FunctionType *CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) { case ABIArgInfo::IndirectAliased: llvm_unreachable("Invalid ABI kind for return argument"); + case ABIArgInfo::TargetSpecific: case ABIArgInfo::Extend: case ABIArgInfo::Direct: resultType = retAI.getCoerceToType(); @@ -1784,6 +1786,7 @@ llvm::FunctionType *CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) { ArgTypes[FirstIRArg] = llvm::PointerType::get( getLLVMContext(), ArgInfo.getIndirectAddrSpace()); break; + case ABIArgInfo::TargetSpecific: case ABIArgInfo::Extend: case ABIArgInfo::Direct: { // Fast-isel and the optimizer generally like scalar values better than @@ -2697,6 +2700,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, else RetAttrs.addAttribute(llvm::Attribute::NoExt); [[fallthrough]]; + case ABIArgInfo::TargetSpecific: case ABIArgInfo::Direct: if (RetAI.getInReg()) RetAttrs.addAttribute(llvm::Attribute::InReg); @@ -2838,6 +2842,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, else Attrs.addAttribute(llvm::Attribute::NoExt); [[fallthrough]]; + case ABIArgInfo::TargetSpecific: case ABIArgInfo::Direct: if (ArgNo == 0 && FI.isChainCall()) Attrs.addAttribute(llvm::Attribute::Nest); @@ -3357,17 +3362,6 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, } } - // Struct of fixed-length vectors and struct of array of fixed-length - // vector in VLS calling convention are coerced to vector tuple - // type(represented as TargetExtType) and scalable vector type - // respectively, they're no longer handled as struct. - if (ArgI.isDirect() && isa<llvm::StructType>(ConvertType(Ty)) && - (isa<llvm::TargetExtType>(ArgI.getCoerceToType()) || - isa<llvm::ScalableVectorType>(ArgI.getCoerceToType()))) { - ArgVals.push_back(ParamValue::forDirect(AI)); - break; - } - llvm::StructType *STy = dyn_cast<llvm::StructType>(ArgI.getCoerceToType()); Address Alloca = @@ -3508,6 +3502,25 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, break; } + case ABIArgInfo::TargetSpecific: { + auto *AI = Fn->getArg(FirstIRArg); + AI->setName(Arg->getName() + ".target_coerce"); + Address Alloca = + CreateMemTemp(Ty, getContext().getDeclAlign(Arg), Arg->getName()); + Address Ptr = emitAddressAtOffset(*this, Alloca, ArgI); + CGM.getABIInfo().createCoercedStore(AI, Ptr, ArgI, false, *this); + if (CodeGenFunction::hasScalarEvaluationKind(Ty)) { + llvm::Value *V = + EmitLoadOfScalar(Alloca, false, Ty, Arg->getBeginLoc()); + if (isPromoted) { + V = emitArgumentDemotion(*this, Arg, V); + } + ArgVals.push_back(ParamValue::forDirect(V)); + } else { + ArgVals.push_back(ParamValue::forIndirect(Alloca)); + } + break; + } case ABIArgInfo::Ignore: assert(NumIRArgs == 0); // Initialize the local variable appropriately. @@ -4136,6 +4149,11 @@ void CodeGenFunction::EmitFunctionEpilog( } break; } + case ABIArgInfo::TargetSpecific: { + Address V = emitAddressAtOffset(*this, ReturnValue, RetAI); + RV = CGM.getABIInfo().createCoercedLoad(V, RetAI, *this); + break; + } case ABIArgInfo::Expand: case ABIArgInfo::IndirectAliased: llvm_unreachable("Invalid ABI kind for return argument"); @@ -5704,6 +5722,24 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, assert(IRArgPos == FirstIRArg + NumIRArgs); break; } + + case ABIArgInfo::TargetSpecific: { + Address Src = Address::invalid(); + if (!I->isAggregate()) { + Src = CreateMemTemp(I->Ty, "target_coerce"); + I->copyInto(*this, Src); + } else { + Src = I->hasLValue() ? I->getKnownLValue().getAddress() + : I->getKnownRValue().getAggregateAddress(); + } + + // If the value is offset in memory, apply the offset now. + Src = emitAddressAtOffset(*this, Src, ArgInfo); + llvm::Value *Load = + CGM.getABIInfo().createCoercedLoad(Src, ArgInfo, *this); + IRCallArgs[FirstIRArg] = Load; + break; + } } } @@ -6189,6 +6225,19 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, return convertTempToRValue(DestPtr, RetTy, SourceLocation()); } + case ABIArgInfo::TargetSpecific: { + Address DestPtr = ReturnValue.getValue(); + Address StorePtr = emitAddressAtOffset(*this, DestPtr, RetAI); + bool DestIsVolatile = ReturnValue.isVolatile(); + if (!DestPtr.isValid()) { + DestPtr = CreateMemTemp(RetTy, "target_coerce"); + DestIsVolatile = false; + } + CGM.getABIInfo().createCoercedStore(CI, StorePtr, RetAI, DestIsVolatile, + *this); + return convertTempToRValue(DestPtr, RetTy, SourceLocation()); + } + case ABIArgInfo::Expand: case ABIArgInfo::IndirectAliased: llvm_unreachable("Invalid ABI kind for return argument"); |