]> granicus.if.org Git - llvm/commitdiff
[ArgPromotion] Preserve alignment of byval argument in new alloca
authorReid Kleckner <rnk@google.com>
Fri, 4 Aug 2017 17:09:11 +0000 (17:09 +0000)
committerReid Kleckner <rnk@google.com>
Fri, 4 Aug 2017 17:09:11 +0000 (17:09 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310071 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/ArgumentPromotion.cpp
test/Transforms/ArgumentPromotion/byval.ll

index 53223ab443161e29b948d5b40254ae658ae71309..72bae203ee94b22466e93c76469bd1805ed205b1 100644 (file)
@@ -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};
index 58475fc89607ba4adc6b7b29528cf07c55caa012..00542e3ec2445637808bbff713a92d59e654dbd9 100644 (file)
@@ -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  {
+entry:
+  %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 @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:
-  %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
 }
 
+; 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  {
-; CHECK-LABEL: define i32 @main
 entry:
-  %S = alloca %struct.ss               ; <%struct.ss*> [#uses=4]
-  %tmp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0               ; <i32*> [#uses=1]
+  %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 %{{.*}})