forked from OSchip/llvm-project
[ArgPromotion] Preserve alignment of byval argument in new alloca
The frontend may have requested a higher alignment for any reason, and downstream optimizations may already have taken advantage of it. We should keep the same alignment when moving the allocation from the parameter area to the local variable area. Fixes PR34038 llvm-svn: 310071
This commit is contained in:
parent
f785fd94c6
commit
da748f1c3d
|
@ -356,7 +356,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
|
|||
// Just add all the struct element types.
|
||||
Type *AgTy = cast<PointerType>(I->getType())->getElementType();
|
||||
Value *TheAlloca = new AllocaInst(AgTy, DL.getAllocaAddrSpace(), nullptr,
|
||||
"", InsertPt);
|
||||
I->getParamAlignment(), "", InsertPt);
|
||||
StructType *STy = cast<StructType>(AgTy);
|
||||
Value *Idxs[2] = {ConstantInt::get(Type::getInt32Ty(F->getContext()), 0),
|
||||
nullptr};
|
||||
|
|
|
@ -6,24 +6,45 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1
|
|||
%struct.ss = type { i32, i64 }
|
||||
|
||||
define internal void @f(%struct.ss* byval %b) nounwind {
|
||||
; CHECK-LABEL: define internal void @f(i32 %b.0, i64 %b.1)
|
||||
entry:
|
||||
%tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0 ; <i32*> [#uses=2]
|
||||
%tmp1 = load i32, i32* %tmp, align 4 ; <i32> [#uses=1]
|
||||
%tmp2 = add i32 %tmp1, 1 ; <i32> [#uses=1]
|
||||
%tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
|
||||
%tmp1 = load i32, i32* %tmp, align 4
|
||||
%tmp2 = add i32 %tmp1, 1
|
||||
store i32 %tmp2, i32* %tmp, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @main() nounwind {
|
||||
; CHECK-LABEL: define i32 @main
|
||||
; CHECK-LABEL: define internal void @f(i32 %b.0, i64 %b.1)
|
||||
; CHECK: alloca %struct.ss{{$}}
|
||||
; CHECK: store i32 %b.0
|
||||
; CHECK: store i64 %b.1
|
||||
|
||||
define internal void @g(%struct.ss* byval align 32 %b) nounwind {
|
||||
entry:
|
||||
%S = alloca %struct.ss ; <%struct.ss*> [#uses=4]
|
||||
%tmp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0 ; <i32*> [#uses=1]
|
||||
%tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
|
||||
%tmp1 = load i32, i32* %tmp, align 4
|
||||
%tmp2 = add i32 %tmp1, 1
|
||||
store i32 %tmp2, i32* %tmp, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: define internal void @g(i32 %b.0, i64 %b.1)
|
||||
; CHECK: alloca %struct.ss, align 32
|
||||
; CHECK: store i32 %b.0
|
||||
; CHECK: store i64 %b.1
|
||||
|
||||
define i32 @main() nounwind {
|
||||
entry:
|
||||
%S = alloca %struct.ss
|
||||
%tmp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0
|
||||
store i32 1, i32* %tmp1, align 8
|
||||
%tmp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1 ; <i64*> [#uses=1]
|
||||
%tmp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1
|
||||
store i64 2, i64* %tmp4, align 4
|
||||
call void @f( %struct.ss* byval %S ) nounwind
|
||||
; CHECK: call void @f(i32 %{{.*}}, i64 %{{.*}})
|
||||
call void @f(%struct.ss* byval %S) nounwind
|
||||
call void @g(%struct.ss* byval %S) nounwind
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
; CHECK-LABEL: define i32 @main
|
||||
; CHECK: call void @f(i32 %{{.*}}, i64 %{{.*}})
|
||||
; CHECK: call void @g(i32 %{{.*}}, i64 %{{.*}})
|
||||
|
|
Loading…
Reference in New Issue