diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -288,6 +288,7 @@ bool IsCFGuardTarget : 1; MaybeAlign Alignment = None; Type *ByValType = nullptr; + Type *InAllocaType = nullptr; Type *PreallocatedType = nullptr; ArgListEntry() diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1741,6 +1741,12 @@ return Ty ? Ty : getArgOperand(ArgNo)->getType()->getPointerElementType(); } + /// Extract the inalloca type for a call or parameter. + Type *getParamInAllocaType(unsigned ArgNo) const { + Type *Ty = Attrs.getParamInAllocaType(ArgNo); + return Ty ? Ty : getArgOperand(ArgNo)->getType()->getPointerElementType(); + } + /// Extract the preallocated type for a call or parameter. Type *getParamPreallocatedType(unsigned ArgNo) const { Type *Ty = Attrs.getParamPreallocatedType(ArgNo); diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1033,7 +1033,7 @@ for (auto &Arg : CLI.getArgs()) { Type *FinalType = Arg.Ty; if (Arg.IsByVal) - FinalType = cast(Arg.Ty)->getElementType(); + FinalType = Arg.ByValType; bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters( FinalType, CLI.CallConv, CLI.IsVarArg); @@ -1074,8 +1074,15 @@ } MaybeAlign MemAlign = Arg.Alignment; if (Arg.IsByVal || Arg.IsInAlloca || Arg.IsPreallocated) { - PointerType *Ty = cast(Arg.Ty); - Type *ElementTy = Ty->getElementType(); + Type *ElementTy; + if (Arg.IsByVal) + ElementTy = Arg.ByValType; + else if (Arg.IsInAlloca) + ElementTy = Arg.InAllocaType; + else + ElementTy = Arg.PreallocatedType; + assert(ElementTy && "Indirect type not set in ArgListEntry"); + unsigned FrameSize = DL.getTypeAllocSize(Arg.ByValType ? Arg.ByValType : ElementTy); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -9409,8 +9409,8 @@ ComputeValueVTs(*this, DL, Args[i].Ty, ValueVTs); // FIXME: Split arguments if CLI.IsPostTypeLegalization Type *FinalType = Args[i].Ty; - if (Args[i].IsByVal) - FinalType = cast(Args[i].Ty)->getElementType(); + if (Args[i].ByValType) + FinalType = Args[i].ByValType; bool NeedsRegBlock = functionArgumentNeedsConsecutiveRegisters( FinalType, CLI.CallConv, CLI.IsVarArg); for (unsigned Value = 0, NumValues = ValueVTs.size(); Value != NumValues; @@ -9481,8 +9481,14 @@ } Align MemAlign; if (Args[i].IsByVal || Args[i].IsInAlloca || Args[i].IsPreallocated) { - PointerType *Ty = cast(Args[i].Ty); - Type *ElementTy = Ty->getElementType(); + Type *ElementTy; + if (Args[i].IsByVal) + ElementTy = Args[i].ByValType; + else if (Args[i].IsInAlloca) + ElementTy = Args[i].InAllocaType; + else + ElementTy = Args[i].PreallocatedType; + assert(ElementTy && "Indirect type not set in ArgListEntry"); unsigned FrameSize = DL.getTypeAllocSize( Args[i].ByValType ? Args[i].ByValType : ElementTy); diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -124,6 +124,9 @@ if (!Alignment) Alignment = Call->getParamAlign(ArgIdx); } + InAllocaType = nullptr; + if (IsInAlloca) + InAllocaType = Call->getParamInAllocaType(ArgIdx); PreallocatedType = nullptr; if (IsPreallocated) PreallocatedType = Call->getParamPreallocatedType(ArgIdx);