From c401de999848e2ea2e7a56361bb56c9854fb4cd7 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 5 Jul 2010 20:21:00 +0000 Subject: [PATCH] in the "coerce" case, the ABI handling code ends up making the alloca for an argument. Make sure the argument gets the proper decl alignment, which may be different than the type alignment. This fixes PR7567 llvm-svn: 107627 --- clang/lib/CodeGen/CGCall.cpp | 6 ++++-- clang/lib/CodeGen/CGExpr.cpp | 8 ++++---- clang/lib/CodeGen/CodeGenFunction.h | 4 ++-- clang/test/CodeGen/x86_64-arguments.c | 10 +++++++++- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index c0c2a4720710..96304477ffc6 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -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 FunctionDecl* FD = dyn_cast_or_null(CurFuncDecl)) { + if (const FunctionDecl *FD = dyn_cast_or_null(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 diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index fe4f7a175223..a8c7199554d8 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -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); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 9466b1c26f9f..18bd625ffd03 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -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. diff --git a/clang/test/CodeGen/x86_64-arguments.c b/clang/test/CodeGen/x86_64-arguments.c index ba9045a1f48e..cc318dc749b3 100644 --- a/clang/test/CodeGen/x86_64-arguments.c +++ b/clang/test/CodeGen/x86_64-arguments.c @@ -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 + +