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 @@ -287,8 +287,8 @@ 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 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1737,14 +1737,17 @@ /// 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 --- 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.IndirectType; bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters( FinalType, CLI.CallConv, CLI.IsVarArg); @@ -1074,10 +1074,10 @@ } 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 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -9410,7 +9410,7 @@ // 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; @@ -9481,11 +9481,10 @@ } 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 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -118,15 +118,23 @@ IsSwiftSelf = Call->paramHasAttr(ArgIdx, Attribute::SwiftSelf); IsSwiftError = Call->paramHasAttr(ArgIdx, Attribute::SwiftError); Alignment = Call->getParamStackAlign(ArgIdx); - ByValType = nullptr; + 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); } - 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