diff options
author | Chris Lattner <sabre@nondot.org> | 2010-12-20 07:45:28 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-12-20 07:45:28 +0000 |
commit | 7394680a00ba525bc1e329e3df234cab1465d031 (patch) | |
tree | af09540001b6fabddd2b0ac2b1f02ba2358854d9 /llvm/lib/Transforms/Utils | |
parent | a9a5c59dd1f82897f6e3240c31e08dc380cdd90e (diff) | |
download | bcm5719-llvm-7394680a00ba525bc1e329e3df234cab1465d031.tar.gz bcm5719-llvm-7394680a00ba525bc1e329e3df234cab1465d031.zip |
fix PR8769, a miscompilation by inliner when inlining a function with a byval
argument. The generated alloca has to have at least the alignment of the
byval, if not, the client may be making assumptions that the new alloca won't
satisfy.
llvm-svn: 122234
Diffstat (limited to 'llvm/lib/Transforms/Utils')
-rw-r--r-- | llvm/lib/Transforms/Utils/InlineFunction.cpp | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 5cf0fed19f4..3f50ccdaf5a 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -252,7 +252,6 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) { CalledFunc->isDeclaration() || // call, or call to a vararg function! CalledFunc->getFunctionType()->isVarArg()) return false; - // If the call to the callee is not a tail call, we must clear the 'tail' // flags on any calls that we inline. bool MustClearTailCallFlags = @@ -308,14 +307,19 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) { if (CalledFunc->paramHasAttr(ArgNo+1, Attribute::ByVal) && !CalledFunc->onlyReadsMemory()) { const Type *AggTy = cast<PointerType>(I->getType())->getElementType(); - const Type *VoidPtrTy = - Type::getInt8PtrTy(Context); + const Type *VoidPtrTy = Type::getInt8PtrTy(Context); // Create the alloca. If we have TargetData, use nice alignment. unsigned Align = 1; - if (IFI.TD) Align = IFI.TD->getPrefTypeAlignment(AggTy); - Value *NewAlloca = new AllocaInst(AggTy, 0, Align, - I->getName(), + if (IFI.TD) + Align = IFI.TD->getPrefTypeAlignment(AggTy); + + // 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 + // pointer inside the callee). + Align = std::max(Align, CalledFunc->getParamAlignment(ArgNo+1)); + + Value *NewAlloca = new AllocaInst(AggTy, 0, Align, I->getName(), &*Caller->begin()->begin()); // Emit a memcpy. const Type *Tys[3] = {VoidPtrTy, VoidPtrTy, Type::getInt64Ty(Context)}; |