diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1375,13 +1375,13 @@ CallerNode->removeCallEdgeFor(*cast(&CB)); } -static void HandleByValArgumentInit(Value *Dst, Value *Src, Module *M, - BasicBlock *InsertBlock, +static void HandleByValArgumentInit(Type *ByValType, Value *Dst, Value *Src, + Module *M, BasicBlock *InsertBlock, InlineFunctionInfo &IFI) { - Type *AggTy = cast(Src->getType())->getElementType(); IRBuilder<> Builder(InsertBlock, InsertBlock->begin()); - Value *Size = Builder.getInt64(M->getDataLayout().getTypeStoreSize(AggTy)); + Value *Size = + Builder.getInt64(M->getDataLayout().getTypeStoreSize(ByValType)); // Always generate a memcpy of alignment 1 here because we don't know // the alignment of the src pointer. Other optimizations can infer @@ -1392,13 +1392,13 @@ /// When inlining a call site that has a byval argument, /// we have to make the implicit memcpy explicit by adding it. -static Value *HandleByValArgument(Value *Arg, Instruction *TheCall, +static Value *HandleByValArgument(Type *ByValType, Value *Arg, + Instruction *TheCall, const Function *CalledFunc, InlineFunctionInfo &IFI, unsigned ByValAlignment) { - PointerType *ArgTy = cast(Arg->getType()); - Type *AggTy = ArgTy->getElementType(); - + assert(cast(Arg->getType()) + ->isOpaqueOrPointeeTypeMatches(ByValType)); Function *Caller = TheCall->getFunction(); const DataLayout &DL = Caller->getParent()->getDataLayout(); @@ -1426,7 +1426,7 @@ } // Create the alloca. If we have DataLayout, use nice alignment. - Align Alignment(DL.getPrefTypeAlignment(AggTy)); + Align Alignment(DL.getPrefTypeAlignment(ByValType)); // If the byval had an alignment specified, we *must* use at least that // alignment, as it is required by the byval argument (and uses of the @@ -1434,7 +1434,7 @@ Alignment = max(Alignment, MaybeAlign(ByValAlignment)); Value *NewAlloca = - new AllocaInst(AggTy, DL.getAllocaAddrSpace(), nullptr, Alignment, + new AllocaInst(ByValType, DL.getAllocaAddrSpace(), nullptr, Alignment, Arg->getName(), &*Caller->begin()->begin()); IFI.StaticAllocas.push_back(cast(NewAlloca)); @@ -1894,8 +1894,13 @@ { // Scope to destroy VMap after cloning. ValueToValueMapTy VMap; + struct ByValInit { + Value *Dst; + Value *Src; + Type *Ty; + }; // Keep a list of pair (dst, src) to emit byval initializations. - SmallVector, 4> ByValInit; + SmallVector ByValInits; // When inlining a function that contains noalias scope metadata, // this metadata needs to be cloned so that the inlined blocks @@ -1920,10 +1925,12 @@ // or readnone, because the copy would be unneeded: the callee doesn't // modify the struct. if (CB.isByValArgument(ArgNo)) { - ActualArg = HandleByValArgument(ActualArg, &CB, CalledFunc, IFI, + ActualArg = HandleByValArgument(CB.getParamByValType(ArgNo), ActualArg, + &CB, CalledFunc, IFI, CalledFunc->getParamAlignment(ArgNo)); if (ActualArg != *AI) - ByValInit.push_back(std::make_pair(ActualArg, (Value*) *AI)); + ByValInits.push_back( + {ActualArg, (Value *)*AI, CB.getParamByValType(ArgNo)}); } VMap[&*I] = ActualArg; @@ -1970,8 +1977,8 @@ } // Inject byval arguments initialization. - for (std::pair &Init : ByValInit) - HandleByValArgumentInit(Init.first, Init.second, Caller->getParent(), + for (ByValInit &Init : ByValInits) + HandleByValArgumentInit(Init.Ty, Init.Dst, Init.Src, Caller->getParent(), &*FirstNewBlock, IFI); Optional ParentDeopt =