diff options
author | Chris Lattner <sabre@nondot.org> | 2010-07-05 20:21:00 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-07-05 20:21:00 +0000 |
commit | c401de999848e2ea2e7a56361bb56c9854fb4cd7 (patch) | |
tree | 80130234fb7201fea03688e33503179e4998a966 /clang | |
parent | 93b283626793d611433c8380ec58dfa93eacd435 (diff) | |
download | bcm5719-llvm-c401de999848e2ea2e7a56361bb56c9854fb4cd7.tar.gz bcm5719-llvm-c401de999848e2ea2e7a56361bb56c9854fb4cd7.zip |
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
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 8 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 4 | ||||
-rw-r--r-- | 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 c0c2a472071..96304477ffc 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<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 diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index fe4f7a17522..a8c7199554d 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 9466b1c26f9..18bd625ffd0 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 ba9045a1f48..cc318dc749b 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 + + |