aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/InlineFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Utils/InlineFunction.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/InlineFunction.cpp27
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);