[cfe-commits] r150196 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/mips64-class-return.cpp

Akira Hatanaka ahatanaka at mips.com
Thu Feb 9 10:49:26 PST 2012


Author: ahatanak
Date: Thu Feb  9 12:49:26 2012
New Revision: 150196

URL: http://llvm.org/viewvc/llvm-project?rev=150196&view=rev
Log:
Fix bugs in function MipsABIInfo::returnAggregateInRegs. Functions returning
class objects follow the same rules as those returning struct objects.


Added:
    cfe/trunk/test/CodeGen/mips64-class-return.cpp
Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=150196&r1=150195&r2=150196&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu Feb  9 12:49:26 2012
@@ -3173,27 +3173,40 @@
 
 llvm::Type*
 MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const {
-  const RecordType *RT = RetTy->getAsStructureType();
+  const RecordType *RT = RetTy->getAs<RecordType>();
   SmallVector<llvm::Type*, 2> RTList;
 
-  if (RT) {
+  if (RT && RT->isStructureOrClassType()) {
     const RecordDecl *RD = RT->getDecl();
-    RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end(), i;
+    const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
+    unsigned FieldCnt = Layout.getFieldCount();
 
-    for (i = b; (i != e) && (std::distance(b, i) < 2); ++i) {
-      const BuiltinType *BT = (*i)->getType()->getAs<BuiltinType>();
+    // N32/64 returns struct/classes in floating point registers if the
+    // following conditions are met:
+    // 1. The size of the struct/class is no larger than 128-bit.
+    // 2. The struct/class has one or two fields all of which are floating
+    //    point types.
+    // 3. The offset of the first field is zero (this follows what gcc does). 
+    //
+    // Any other composite results are returned in integer registers.
+    //
+    if (FieldCnt && (FieldCnt <= 2) && !Layout.getFieldOffset(0)) {
+      RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end();
+      for (; b != e; ++b) {
+        const BuiltinType *BT = (*b)->getType()->getAs<BuiltinType>();
 
-      if (!BT || !BT->isFloatingPoint())
-        break;
+        if (!BT || !BT->isFloatingPoint())
+          break;
 
-      RTList.push_back(CGT.ConvertType((*i)->getType()));
-    }
+        RTList.push_back(CGT.ConvertType((*b)->getType()));
+      }
 
-    if (i == e)
-      return llvm::StructType::get(getVMContext(), RTList,
-                                   RD->hasAttr<PackedAttr>());
+      if (b == e)
+        return llvm::StructType::get(getVMContext(), RTList,
+                                     RD->hasAttr<PackedAttr>());
 
-    RTList.clear();
+      RTList.clear();
+    }
   }
 
   RTList.push_back(llvm::IntegerType::get(getVMContext(),

Added: cfe/trunk/test/CodeGen/mips64-class-return.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/mips64-class-return.cpp?rev=150196&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/mips64-class-return.cpp (added)
+++ cfe/trunk/test/CodeGen/mips64-class-return.cpp Thu Feb  9 12:49:26 2012
@@ -0,0 +1,31 @@
+// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s
+
+class B0 {
+  double d;
+};
+
+class D0 : public B0 {
+  float f;
+};
+
+class B1 {
+};
+
+class D1 : public B1 {
+  double d;
+  float f;
+};
+
+extern D0 gd0;
+extern D1 gd1;
+
+// CHECK: define { i64, i64 } @_Z4foo1v() 
+D0 foo1(void) {
+  return gd0;
+}
+
+// CHECK: define { double, float } @_Z4foo2v() 
+D1 foo2(void) {
+  return gd1;
+}
+





More information about the cfe-commits mailing list