[cfe-commits] r73306 - in /cfe/trunk: lib/CodeGen/TargetABIInfo.cpp test/CodeGen/x86_32-arguments.c

Eli Friedman eli.friedman at gmail.com
Sat Jun 13 14:37:12 PDT 2009


Author: efriedma
Date: Sat Jun 13 16:37:10 2009
New Revision: 73306

URL: http://llvm.org/viewvc/llvm-project?rev=73306&view=rev
Log:
Fix the calling convention for structs/unions containing SSE vectors on 
x86-32.  This is slightly messy, but I think it's consistent with gcc.


Modified:
    cfe/trunk/lib/CodeGen/TargetABIInfo.cpp
    cfe/trunk/test/CodeGen/x86_32-arguments.c

Modified: cfe/trunk/lib/CodeGen/TargetABIInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetABIInfo.cpp?rev=73306&r1=73305&r2=73306&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/TargetABIInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetABIInfo.cpp Sat Jun 13 16:37:10 2009
@@ -159,6 +159,23 @@
   return true;
 }
 
+static bool typeContainsSSEVector(const RecordDecl *RD, ASTContext &Context) {
+  for (RecordDecl::field_iterator i = RD->field_begin(Context),
+         e = RD->field_end(Context); i != e; ++i) {
+    const FieldDecl *FD = *i;
+
+    if (FD->getType()->isVectorType() &&
+        Context.getTypeSize(FD->getType()) >= 128)
+      return true;
+
+    if (const RecordType* RT = FD->getType()->getAsRecordType())
+      if (typeContainsSSEVector(RT->getDecl(), Context))
+        return true;
+  }
+
+  return false;
+}
+
 namespace {
 /// DefaultABIInfo - The default implementation for ABI specific
 /// details. This implementation provides information which results in
@@ -193,6 +210,9 @@
 
   static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context);
 
+  static unsigned getIndirectArgumentAlignment(QualType Ty,
+                                               ASTContext &Context);
+
 public:
   ABIArgInfo classifyReturnType(QualType RetTy,
                                 ASTContext &Context) const;
@@ -350,6 +370,16 @@
   }
 }
 
+unsigned X86_32ABIInfo::getIndirectArgumentAlignment(QualType Ty,
+                                                     ASTContext &Context) {
+  unsigned Align = Context.getTypeAlign(Ty);
+  if (Align < 128) return 0;
+  if (const RecordType* RT = Ty->getAsRecordType())
+    if (typeContainsSSEVector(RT->getDecl(), Context))
+      return 16;
+  return 0;
+}
+
 ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
                                                ASTContext &Context) const {
   // FIXME: Set alignment on indirect arguments.
@@ -357,11 +387,11 @@
     // Structures with flexible arrays are always indirect.
     if (const RecordType *RT = Ty->getAsStructureType())
       if (RT->getDecl()->hasFlexibleArrayMember())
-        return ABIArgInfo::getIndirect(0);
+        return ABIArgInfo::getIndirect(getIndirectArgumentAlignment(Ty, 
+                                                                    Context));
 
     // Ignore empty structs.
-    uint64_t Size = Context.getTypeSize(Ty);
-    if (Ty->isStructureType() && Size == 0)
+    if (Ty->isStructureType() && Context.getTypeSize(Ty) == 0)
       return ABIArgInfo::getIgnore();
 
     // Expand structs with size <= 128-bits which consist only of
@@ -373,7 +403,7 @@
         return ABIArgInfo::getExpand();
     }
 
-    return ABIArgInfo::getIndirect(0);
+    return ABIArgInfo::getIndirect(getIndirectArgumentAlignment(Ty, Context));
   } else {
     return (Ty->isPromotableIntegerType() ?
             ABIArgInfo::getExtend() : ABIArgInfo::getDirect());

Modified: cfe/trunk/test/CodeGen/x86_32-arguments.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_32-arguments.c?rev=73306&r1=73305&r2=73306&view=diff

==============================================================================
--- cfe/trunk/test/CodeGen/x86_32-arguments.c (original)
+++ cfe/trunk/test/CodeGen/x86_32-arguments.c Sat Jun 13 16:37:10 2009
@@ -154,4 +154,9 @@
 // RUN: grep 'define void @f38(.struct.s38. noalias sret .agg.result)' %t &&
 struct s38 { char a[3]; short b; } f38(void) {}
 
+// RUN: grep 'define void @f39(.struct.s39. byval align 16 .x)' %t &&
+typedef int v39 __attribute((vector_size(16)));
+struct s39 { v39 x; };
+void f39(struct s39 x) {}
+
 // RUN: true





More information about the cfe-commits mailing list