Index: llvm/include/llvm/IR/Argument.h =================================================================== --- llvm/include/llvm/IR/Argument.h +++ llvm/include/llvm/IR/Argument.h @@ -75,6 +75,10 @@ /// attribute. These attributes represent arguments being passed by value. bool hasPassPointeeByValueAttr() const; + /// If this argument satisfies has hasPassPointeeByValueAttr, return the + /// in-memory ABI size copied to the stack for the call. Otherwise, return 0. + uint64_t getPassPointeeByValueCopySize(const DataLayout &DL) const; + /// If this is a byval or inalloca argument, return its alignment. /// FIXME: Remove this function once transition to Align is over. /// Use getParamAlign() instead. Index: llvm/lib/IR/Function.cpp =================================================================== --- llvm/lib/IR/Function.cpp +++ llvm/lib/IR/Function.cpp @@ -128,6 +128,27 @@ Attrs.hasParamAttribute(getArgNo(), Attribute::Preallocated); } +uint64_t Argument::getPassPointeeByValueCopySize(const DataLayout &DL) const { + AttributeSet ParamAttrs + = getParent()->getAttributes().getParamAttributes(getArgNo()); + + // FIXME: All the type carrying attributes are mutually exclusive, so there + // should be a single query to get the stored type that handles any of them. + if (Type *ByValTy = ParamAttrs.getByValType()) + return DL.getTypeAllocSize(ByValTy); + if (Type *PreAllocTy = ParamAttrs.getPreallocatedType()) + return DL.getTypeAllocSize(PreAllocTy); + + // FIXME: inalloca always depends on pointee element type. It's also possible + // for byval to miss it. + if (ParamAttrs.hasAttribute(Attribute::InAlloca) || + ParamAttrs.hasAttribute(Attribute::ByVal) || + ParamAttrs.hasAttribute(Attribute::Preallocated)) + return DL.getTypeAllocSize(cast(getType())->getElementType()); + + return 0; +} + unsigned Argument::getParamAlignment() const { assert(getType()->isPointerTy() && "Only pointers have alignments"); return getParent()->getParamAlignment(getArgNo()); Index: llvm/lib/IR/Mangler.cpp =================================================================== --- llvm/lib/IR/Mangler.cpp +++ llvm/lib/IR/Mangler.cpp @@ -94,15 +94,18 @@ const DataLayout &DL) { // Calculate arguments size total. unsigned ArgWords = 0; + + const unsigned PtrSize = DL.getPointerSize(); + for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI) { - Type *Ty = AI->getType(); // 'Dereference' type in case of byval or inalloca parameter attribute. - if (AI->hasPassPointeeByValueAttr()) - Ty = cast(Ty)->getElementType(); + uint64_t AllocSize = AI->hasPassPointeeByValueAttr() ? + AI->getPassPointeeByValueCopySize(DL) : + DL.getTypeAllocSize(AI->getType()); + // Size should be aligned to pointer size. - unsigned PtrSize = DL.getPointerSize(); - ArgWords += alignTo(DL.getTypeAllocSize(Ty), PtrSize); + ArgWords += alignTo(AllocSize, PtrSize); } OS << '@' << ArgWords;