]> granicus.if.org Git - clang/commitdiff
in the "coerce" case, the ABI handling code ends up making the
authorChris Lattner <sabre@nondot.org>
Mon, 5 Jul 2010 20:21:00 +0000 (20:21 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 5 Jul 2010 20:21:00 +0000 (20:21 +0000)
alloca for an argument.  Make sure the argument gets the proper
decl alignment, which may be different than the type alignment.

This fixes PR7567

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

lib/CodeGen/CGCall.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGen/x86_64-arguments.c

index c0c2a4720710e0e30dc5031c173efdbb4c2d729c..96304477ffc68e9cf43cfaa9270521f7414b616a 100644 (file)
@@ -819,7 +819,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
   // initialize the return value.  TODO: it might be nice to have
   // a more general mechanism for this that didn't require synthesized
   // return statements.
-  if (const FunctionDeclFD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) {
+  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) {
     if (FD->hasImplicitReturnZero()) {
       QualType RetTy = FD->getResultType().getUnqualifiedType();
       const llvm::Type* LLVMTy = CGM.getTypes().ConvertType(RetTy);
@@ -924,7 +924,9 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
       // FIXME: This is very wasteful; EmitParmDecl is just going to drop the
       // result in a new alloca anyway, so we could just store into that
       // directly if we broke the abstraction down more.
-      llvm::Value *V = CreateMemTemp(Ty, "coerce");
+      llvm::AllocaInst *Alloca = CreateMemTemp(Ty, "coerce");
+      Alloca->setAlignment(getContext().getDeclAlign(Arg).getQuantity());
+      llvm::Value *V = Alloca;
       
       // If the coerce-to type is a first class aggregate, we flatten it and
       // pass the elements. Either way is semantically identical, but fast-isel
index fe4f7a175223b0af789ad15faae6254855f64dd6..a8c7199554d865b8835373a29f0719f243595e50 100644 (file)
@@ -44,8 +44,8 @@ void CodeGenFunction::InitTempAlloca(llvm::AllocaInst *Var,
   Block->getInstList().insertAfter(&*AllocaInsertPt, Store);
 }
 
-llvm::Value *CodeGenFunction::CreateIRTemp(QualType Ty,
-                                           const llvm::Twine &Name) {
+llvm::AllocaInst *CodeGenFunction::CreateIRTemp(QualType Ty,
+                                                const llvm::Twine &Name) {
   llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertType(Ty), Name);
   // FIXME: Should we prefer the preferred type alignment here?
   CharUnits Align = getContext().getTypeAlignInChars(Ty);
@@ -53,8 +53,8 @@ llvm::Value *CodeGenFunction::CreateIRTemp(QualType Ty,
   return Alloc;
 }
 
-llvm::Value *CodeGenFunction::CreateMemTemp(QualType Ty,
-                                            const llvm::Twine &Name) {
+llvm::AllocaInst *CodeGenFunction::CreateMemTemp(QualType Ty,
+                                                 const llvm::Twine &Name) {
   llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertTypeForMem(Ty), Name);
   // FIXME: Should we prefer the preferred type alignment here?
   CharUnits Align = getContext().getTypeAlignInChars(Ty);
index 9466b1c26f9f08fb5aa4d282d43b490b64d58711..18bd625ffd03a29eaa6e77340595d1f2add4ecfd 100644 (file)
@@ -698,11 +698,11 @@ public:
   /// value needs to be stored into an alloca (for example, to avoid explicit
   /// PHI construction), but the type is the IR type, not the type appropriate
   /// for storing in memory.
-  llvm::Value *CreateIRTemp(QualType T, const llvm::Twine &Name = "tmp");
+  llvm::AllocaInst *CreateIRTemp(QualType T, const llvm::Twine &Name = "tmp");
 
   /// CreateMemTemp - Create a temporary memory object of the given type, with
   /// appropriate alignment.
-  llvm::Value *CreateMemTemp(QualType T, const llvm::Twine &Name = "tmp");
+  llvm::AllocaInst *CreateMemTemp(QualType T, const llvm::Twine &Name = "tmp");
 
   /// EvaluateExprAsBool - Perform the usual unary conversions on the specified
   /// expression and compare the result against zero, returning an Int1Ty value.
index ba9045a1f48e61fbb3ec59692ed1500d36cf18ae..cc318dc749b36082073eab43a1896777f88babb6 100644 (file)
@@ -71,7 +71,7 @@ void f12_1(struct s12 a0) {}
 
 // Check that sret parameter is accounted for when checking available integer
 // registers.
-// CHECK: define void @f13(%struct.s13_0* sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, %struct.s13_1* byval %e, i32 %f)
+// CHECK: define void @f13(%struct.s13_0* sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, {{.*}}* byval %e, i32 %f)
 
 struct s13_0 { long long f0[3]; };
 struct s13_1 { long long f0[2]; };
@@ -123,3 +123,11 @@ struct StringRef {
 // CHECK: define i8* @f21(i64 %S.coerce0, i8* %S.coerce1) 
 const char *f21(struct StringRef S) { return S.x+S.Ptr; }
 
+// PR7567
+typedef __attribute__ ((aligned(16))) struct f22s { unsigned long long x[2]; } L;
+void f22(L x, L y) { }
+// CHECK: @f22
+// CHECK: %x = alloca{{.*}}, align 16
+// CHECK: %y = alloca{{.*}}, align 16
+
+