mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-17 03:30:28 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122234 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
572335915f
commit
018fb767b9
@ -252,7 +252,6 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {
|
|||||||
CalledFunc->isDeclaration() || // call, or call to a vararg function!
|
CalledFunc->isDeclaration() || // call, or call to a vararg function!
|
||||||
CalledFunc->getFunctionType()->isVarArg()) return false;
|
CalledFunc->getFunctionType()->isVarArg()) return false;
|
||||||
|
|
||||||
|
|
||||||
// If the call to the callee is not a tail call, we must clear the 'tail'
|
// If the call to the callee is not a tail call, we must clear the 'tail'
|
||||||
// flags on any calls that we inline.
|
// flags on any calls that we inline.
|
||||||
bool MustClearTailCallFlags =
|
bool MustClearTailCallFlags =
|
||||||
@ -308,14 +307,19 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {
|
|||||||
if (CalledFunc->paramHasAttr(ArgNo+1, Attribute::ByVal) &&
|
if (CalledFunc->paramHasAttr(ArgNo+1, Attribute::ByVal) &&
|
||||||
!CalledFunc->onlyReadsMemory()) {
|
!CalledFunc->onlyReadsMemory()) {
|
||||||
const Type *AggTy = cast<PointerType>(I->getType())->getElementType();
|
const Type *AggTy = cast<PointerType>(I->getType())->getElementType();
|
||||||
const Type *VoidPtrTy =
|
const Type *VoidPtrTy = Type::getInt8PtrTy(Context);
|
||||||
Type::getInt8PtrTy(Context);
|
|
||||||
|
|
||||||
// Create the alloca. If we have TargetData, use nice alignment.
|
// Create the alloca. If we have TargetData, use nice alignment.
|
||||||
unsigned Align = 1;
|
unsigned Align = 1;
|
||||||
if (IFI.TD) Align = IFI.TD->getPrefTypeAlignment(AggTy);
|
if (IFI.TD)
|
||||||
Value *NewAlloca = new AllocaInst(AggTy, 0, Align,
|
Align = IFI.TD->getPrefTypeAlignment(AggTy);
|
||||||
I->getName(),
|
|
||||||
|
// 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());
|
&*Caller->begin()->begin());
|
||||||
// Emit a memcpy.
|
// Emit a memcpy.
|
||||||
const Type *Tys[3] = {VoidPtrTy, VoidPtrTy, Type::getInt64Ty(Context)};
|
const Type *Tys[3] = {VoidPtrTy, VoidPtrTy, Type::getInt64Ty(Context)};
|
||||||
|
@ -56,3 +56,27 @@ entry:
|
|||||||
; CHECK-NOT: call void @llvm.memcpy
|
; CHECK-NOT: call void @llvm.memcpy
|
||||||
; CHECK: ret i32
|
; CHECK: ret i32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
; Inlining a byval with an explicit alignment needs to use *at least* that
|
||||||
|
; alignment on the generated alloca.
|
||||||
|
; PR8769
|
||||||
|
declare void @g3(%struct.ss* %p)
|
||||||
|
|
||||||
|
define internal void @f3(%struct.ss* byval align 64 %b) nounwind {
|
||||||
|
call void @g3(%struct.ss* %b) ;; Could make alignment assumptions!
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @test3() nounwind {
|
||||||
|
entry:
|
||||||
|
%S = alloca %struct.ss, align 1 ;; May not be aligned.
|
||||||
|
call void @f3( %struct.ss* byval align 64 %S) nounwind
|
||||||
|
ret void
|
||||||
|
; CHECK: @test3()
|
||||||
|
; CHECK: %b = alloca %struct.ss, align 64
|
||||||
|
; CHECK: %S = alloca %struct.ss
|
||||||
|
; CHECK: call void @llvm.memcpy
|
||||||
|
; CHECK: call void @g3(%struct.ss* %b)
|
||||||
|
; CHECK: ret void
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user