diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index fe2adde8195d..13079b8f17fc 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -290,8 +290,8 @@ public: bool IsSwiftError : 1; bool IsCFGuardTarget : 1; MaybeAlign Alignment = None; - Type *ByValType = nullptr; - Type *PreallocatedType = nullptr; + // Type for byval, inalloca, or preallocated. + Type *IndirectType = nullptr; ArgListEntry() : IsSExt(false), IsZExt(false), IsInReg(false), IsSRet(false), diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index f1e743f87eab..39a10aae0058 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1722,14 +1722,17 @@ public: /// Extract the byval type for a call or parameter. Type *getParamByValType(unsigned ArgNo) const { - Type *Ty = Attrs.getParamByValType(ArgNo); - return Ty ? Ty : getArgOperand(ArgNo)->getType()->getPointerElementType(); + return Attrs.getParamByValType(ArgNo); + } + + /// Extract the inalloca type for a call or parameter. + Type *getParamInAllocaType(unsigned ArgNo) const { + return Attrs.getParamInAllocaType(ArgNo); } /// Extract the preallocated type for a call or parameter. Type *getParamPreallocatedType(unsigned ArgNo) const { - Type *Ty = Attrs.getParamPreallocatedType(ArgNo); - return Ty ? Ty : getArgOperand(ArgNo)->getType()->getPointerElementType(); + return Attrs.getParamPreallocatedType(ArgNo); } /// Extract the number of dereferenceable bytes for a call or diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index c5a3aa53439b..514cfc6632a3 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1033,7 +1033,7 @@ bool FastISel::lowerCallTo(CallLoweringInfo &CLI) { for (auto &Arg : CLI.getArgs()) { Type *FinalType = Arg.Ty; if (Arg.IsByVal) - FinalType = cast(Arg.Ty)->getElementType(); + FinalType = Arg.IndirectType; bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters( FinalType, CLI.CallConv, CLI.IsVarArg); @@ -1076,10 +1076,10 @@ bool FastISel::lowerCallTo(CallLoweringInfo &CLI) { } MaybeAlign MemAlign = Arg.Alignment; if (Arg.IsByVal || Arg.IsInAlloca || Arg.IsPreallocated) { - PointerType *Ty = cast(Arg.Ty); - Type *ElementTy = Ty->getElementType(); - unsigned FrameSize = - DL.getTypeAllocSize(Arg.ByValType ? Arg.ByValType : ElementTy); + Type *ElementTy = Arg.IndirectType; + assert(ElementTy && "Indirect type not set in ArgListEntry"); + + unsigned FrameSize = DL.getTypeAllocSize(ElementTy); // For ByVal, alignment should come from FE. BE will guess if this info // is not there, but there are cases it cannot get right. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 945beec6f1cd..4f37f862b175 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -9464,7 +9464,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const { // FIXME: Split arguments if CLI.IsPostTypeLegalization Type *FinalType = Args[i].Ty; if (Args[i].IsByVal) - FinalType = cast(Args[i].Ty)->getElementType(); + FinalType = Args[i].IndirectType; bool NeedsRegBlock = functionArgumentNeedsConsecutiveRegisters( FinalType, CLI.CallConv, CLI.IsVarArg); for (unsigned Value = 0, NumValues = ValueVTs.size(); Value != NumValues; @@ -9537,11 +9537,10 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const { } Align MemAlign; if (Args[i].IsByVal || Args[i].IsInAlloca || Args[i].IsPreallocated) { - PointerType *Ty = cast(Args[i].Ty); - Type *ElementTy = Ty->getElementType(); + Type *ElementTy = Args[i].IndirectType; + assert(ElementTy && "Indirect type not set in ArgListEntry"); - unsigned FrameSize = DL.getTypeAllocSize( - Args[i].ByValType ? Args[i].ByValType : ElementTy); + unsigned FrameSize = DL.getTypeAllocSize(ElementTy); Flags.setByValSize(FrameSize); // info is not there but there are cases it cannot get right. diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 30393298ab72..8950bd9a301c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -120,17 +120,26 @@ void TargetLoweringBase::ArgListEntry::setAttributes(const CallBase *Call, Alignment = Attrs.getParamStackAlignment(ArgIdx); IsByVal = Attrs.hasParamAttribute(ArgIdx, Attribute::ByVal); - ByValType = nullptr; + IsInAlloca = Attrs.hasParamAttribute(ArgIdx, Attribute::InAlloca); + IsPreallocated = Attrs.hasParamAttribute(ArgIdx, Attribute::Preallocated); + + assert(IsByVal + IsInAlloca + IsPreallocated <= 1 && + "can't have multiple indirect attributes"); + IndirectType = nullptr; if (IsByVal) { - ByValType = Call->getParamByValType(ArgIdx); + IndirectType = Call->getParamByValType(ArgIdx); + assert(IndirectType && "no byval type?"); if (!Alignment) Alignment = Call->getParamAlign(ArgIdx); } - IsInAlloca = Attrs.hasParamAttribute(ArgIdx, Attribute::InAlloca); - IsPreallocated = Attrs.hasParamAttribute(ArgIdx, Attribute::Preallocated); - PreallocatedType = nullptr; - if (IsPreallocated) - PreallocatedType = Call->getParamPreallocatedType(ArgIdx); + if (IsInAlloca) { + IndirectType = Call->getParamInAllocaType(ArgIdx); + assert(IndirectType && "no inalloca type?"); + } + if (IsPreallocated) { + IndirectType = Call->getParamPreallocatedType(ArgIdx); + assert(IndirectType && "no preallocated type?"); + } } /// Generate a libcall taking the given operands as arguments and returning a