// 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);
// 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
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);
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);
/// 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.
// 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]; };
// 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
+
+