diff options
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 6 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 4 | ||||
-rw-r--r-- | test/CodeGen/x86_64-arguments.c | 10 |
4 files changed, 19 insertions, 9 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index c0c2a47207..96304477ff 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/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/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index fe4f7a1752..a8c7199554 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/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/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 9466b1c26f..18bd625ffd 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/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/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c index ba9045a1f4..cc318dc749 100644 --- a/test/CodeGen/x86_64-arguments.c +++ b/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 + + |