[cfe-commits] r144960 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/x86_32-arguments-darwin.c test/CodeGenCXX/x86_32-arguments.cpp

Eli Friedman eli.friedman at gmail.com
Thu Nov 17 17:25:51 PST 2011


Author: efriedma
Date: Thu Nov 17 19:25:50 2011
New Revision: 144960

URL: http://llvm.org/viewvc/llvm-project?rev=144960&view=rev
Log:
Simplify code for returning a struct for Darwin x86-32 ABI.  Use a better type for a function returning a struct containing only a pointer.  Handle the edge case of a struct containing only a float or double plus some dead padding instead of asserting.


Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c
    cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=144960&r1=144959&r2=144960&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu Nov 17 19:25:50 2011
@@ -252,6 +252,11 @@
     }
   }
 
+  // We don't consider a struct a single-element struct if it has
+  // padding beyond the element type.
+  if (Found && Context.getTypeSize(Found) != Context.getTypeSize(T))
+    return 0;
+
   return Found;
 }
 
@@ -561,51 +566,21 @@
     if (!IsSmallStructInRegABI && !RetTy->isAnyComplexType())
       return ABIArgInfo::getIndirect(0);
 
-    // Classify "single element" structs as their element type.
-    if (const Type *SeltTy = isSingleElementStruct(RetTy, getContext())) {
-      if (const BuiltinType *BT = SeltTy->getAs<BuiltinType>()) {
-        if (BT->isIntegerType()) {
-          // We need to use the size of the structure, padding
-          // bit-fields can adjust that to be larger than the single
-          // element type.
-          uint64_t Size = getContext().getTypeSize(RetTy);
-          return ABIArgInfo::getDirect(
-            llvm::IntegerType::get(getVMContext(), (unsigned)Size));
-        }
-
-        if (BT->getKind() == BuiltinType::Float) {
-          assert(getContext().getTypeSize(RetTy) ==
-                 getContext().getTypeSize(SeltTy) &&
-                 "Unexpect single element structure size!");
-          return ABIArgInfo::getDirect(llvm::Type::getFloatTy(getVMContext()));
-        }
-
-        if (BT->getKind() == BuiltinType::Double) {
-          assert(getContext().getTypeSize(RetTy) ==
-                 getContext().getTypeSize(SeltTy) &&
-                 "Unexpect single element structure size!");
-          return ABIArgInfo::getDirect(llvm::Type::getDoubleTy(getVMContext()));
-        }
-      } else if (SeltTy->isPointerType()) {
-        // FIXME: It would be really nice if this could come out as the proper
-        // pointer type.
-        llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(getVMContext());
-        return ABIArgInfo::getDirect(PtrTy);
-      } else if (SeltTy->isVectorType()) {
-        // 64- and 128-bit vectors are never returned in a
-        // register when inside a structure.
-        uint64_t Size = getContext().getTypeSize(RetTy);
-        if (Size == 64 || Size == 128)
-          return ABIArgInfo::getIndirect(0);
-
-        return classifyReturnType(QualType(SeltTy, 0));
-      }
-    }
-
     // Small structures which are register sized are generally returned
     // in a register.
     if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext())) {
       uint64_t Size = getContext().getTypeSize(RetTy);
+
+      // As a special-case, if the struct is a "single-element" struct, and
+      // the field is of type "float" or "double", return it in a
+      // floating-point register.  We apply a similar transformation for
+      // pointer types to improve the quality of the generated IR.
+      if (const Type *SeltTy = isSingleElementStruct(RetTy, getContext()))
+        if (SeltTy->isRealFloatingType() || SeltTy->hasPointerRepresentation())
+          return ABIArgInfo::getDirect(CGT.ConvertType(QualType(SeltTy, 0)));
+
+      // FIXME: We should be able to narrow this integer in cases with dead
+      // padding.
       return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),Size));
     }
 

Modified: cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c?rev=144960&r1=144959&r2=144960&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c (original)
+++ cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c Thu Nov 17 19:25:50 2011
@@ -173,7 +173,7 @@
 // CHECK: define i64 @f43()
 struct s43 { enum e40 f0; int f1; } f43(void) {  }
 
-// CHECK: define i32 @f44()
+// CHECK: define void ()* @f44()
 struct s44 { vvbp f0; } f44(void) {  }
 
 // CHECK: define i64 @f45()
@@ -281,6 +281,10 @@
 struct s57 { _Complex int x; };
 void f57(struct s57 x) {} void f57a(void) { f57((struct s57){1}); }
 
+// CHECK: define void @f58()
 union u58 {};
 void f58(union u58 x) {}
-// CHECK: define void @f58()
+
+// CHECK: define i64 @f59()
+struct s59 { float x __attribute((aligned(8))); };
+struct s59 f59() { while (1) {} }

Modified: cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp?rev=144960&r1=144959&r2=144960&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp Thu Nov 17 19:25:50 2011
@@ -84,7 +84,7 @@
 struct s4_2 : s4_0, s4_1 { };
 s4_2 f4() { return s4_2(); }
 
-// CHECK: define i32 @_Z2f5v()
+// CHECK: define i32* @_Z2f5v()
 struct s5 { s5(); int &x; };
 s5 f5() { return s5(); }
 





More information about the cfe-commits mailing list