From a34e92116581531f7325527d952a9ffcc819d905 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 9 Feb 2012 19:54:16 +0000 Subject: [PATCH] Class objects passed by value follow the same rules as structure objects. Double fields of by-value class objects should be passed in floating point registers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150200 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TargetInfo.cpp | 9 ++++++--- test/CodeGen/mips64-class-return.cpp | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index b48bff8a1e..cae8f5fb1a 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -3065,9 +3065,10 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty) const { if (Ty->isComplexType()) return CGT.ConvertType(Ty); - const RecordType *RT = Ty->getAsStructureType(); + const RecordType *RT = Ty->getAs(); - if (!RT) + // Unions are passed in integer registers. + if (!RT || !RT->isStructureOrClassType()) return 0; const RecordDecl *RD = RT->getDecl(); @@ -3080,6 +3081,8 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty) const { llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64); SmallVector ArgList; + // Iterate over fields in the struct/class and check if there are any aligned + // double fields. for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); i != e; ++i, ++idx) { const QualType Ty = (*i)->getType(); @@ -3101,7 +3104,7 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty) const { LastOffset = Offset + 64; } - // This structure doesn't have an aligned double field. + // This struct/class doesn't have an aligned double field. if (!LastOffset) return 0; diff --git a/test/CodeGen/mips64-class-return.cpp b/test/CodeGen/mips64-class-return.cpp index eca8d5b2f7..dc9ec0f5be 100644 --- a/test/CodeGen/mips64-class-return.cpp +++ b/test/CodeGen/mips64-class-return.cpp @@ -16,8 +16,13 @@ class D1 : public B1 { float f; }; +class D2 : public B0 { + double d2; +}; + extern D0 gd0; extern D1 gd1; +extern D2 gd2; // CHECK: define { i64, i64 } @_Z4foo1v() D0 foo1(void) { @@ -29,3 +34,13 @@ D1 foo2(void) { return gd1; } +// CHECK: define void @_Z4foo32D2(i64 %a0.coerce0, double %a0.coerce1) +void foo3(D2 a0) { + gd2 = a0; +} + +// CHECK: define void @_Z4foo42D0(%class.D0* nocapture byval %a0) +void foo4(D0 a0) { + gd0 = a0; +} + -- 2.40.0