diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/InlineFunction.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/InlineFunction.cpp | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 295518f..7a91620 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1703,7 +1703,8 @@ static void AddAlignmentAssumptions(CallBase &CB, InlineFunctionInfo &IFI) { } static void HandleByValArgumentInit(Type *ByValType, Value *Dst, Value *Src, - Module *M, BasicBlock *InsertBlock, + MaybeAlign SrcAlign, Module *M, + BasicBlock *InsertBlock, InlineFunctionInfo &IFI, Function *CalledFunc) { IRBuilder<> Builder(InsertBlock, InsertBlock->begin()); @@ -1711,11 +1712,10 @@ static void HandleByValArgumentInit(Type *ByValType, Value *Dst, Value *Src, 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 - // better alignment. - CallInst *CI = Builder.CreateMemCpy(Dst, /*DstAlign*/ Align(1), Src, - /*SrcAlign*/ Align(1), Size); + Align DstAlign = Dst->getPointerAlignment(M->getDataLayout()); + + // Generate a memcpy with the correct alignments. + CallInst *CI = Builder.CreateMemCpy(Dst, DstAlign, Src, SrcAlign, Size); // The verifier requires that all calls of debug-info-bearing functions // from debug-info-bearing functions have a debug location (for inlining @@ -2629,9 +2629,12 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, struct ByValInit { Value *Dst; Value *Src; + MaybeAlign SrcAlign; Type *Ty; }; - // Keep a list of pair (dst, src) to emit byval initializations. + // Keep a list of tuples (dst, src, src_align) to emit byval + // initializations. Src Alignment is only available though the callbase, + // therefore has to be saved. SmallVector<ByValInit, 4> ByValInits; // When inlining a function that contains noalias scope metadata, @@ -2661,8 +2664,9 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, &CB, CalledFunc, IFI, CalledFunc->getParamAlign(ArgNo)); if (ActualArg != *AI) - ByValInits.push_back( - {ActualArg, (Value *)*AI, CB.getParamByValType(ArgNo)}); + ByValInits.push_back({ActualArg, (Value *)*AI, + CB.getParamAlign(ArgNo), + CB.getParamByValType(ArgNo)}); } VMap[&*I] = ActualArg; @@ -2712,8 +2716,9 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, // Inject byval arguments initialization. for (ByValInit &Init : ByValInits) - HandleByValArgumentInit(Init.Ty, Init.Dst, Init.Src, Caller->getParent(), - &*FirstNewBlock, IFI, CalledFunc); + HandleByValArgumentInit(Init.Ty, Init.Dst, Init.Src, Init.SrcAlign, + Caller->getParent(), &*FirstNewBlock, IFI, + CalledFunc); std::optional<OperandBundleUse> ParentDeopt = CB.getOperandBundle(LLVMContext::OB_deopt); |