[cfe-commits] r102019 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/x86_32-arguments.c test/CodeGen/x86_64-arguments.c

Daniel Dunbar daniel at zuster.org
Wed Apr 21 12:49:55 PDT 2010


Author: ddunbar
Date: Wed Apr 21 14:49:55 2010
New Revision: 102019

URL: http://llvm.org/viewvc/llvm-project?rev=102019&view=rev
Log:
ABI/x86-32 & x86-64: Alignment on 'byval' must be set when when the alignment
exceeds the minimum ABI alignment.

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

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=102019&r1=102018&r2=102019&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed Apr 21 14:49:55 2010
@@ -292,9 +292,6 @@
 
   static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context);
 
-  static unsigned getIndirectArgumentAlignment(QualType Ty,
-                                               ASTContext &Context);
-
   /// getIndirectResult - Give a source type \arg Ty, return a suitable result
   /// such that the argument will be passed in memory.
   ABIArgInfo getIndirectResult(QualType Ty, ASTContext &Context,
@@ -496,21 +493,19 @@
   }
 }
 
-unsigned X86_32ABIInfo::getIndirectArgumentAlignment(QualType Ty,
-                                                     ASTContext &Context) {
-  unsigned Align = Context.getTypeAlign(Ty);
-  if (Align < 128) return 0;
-  if (const RecordType* RT = Ty->getAs<RecordType>())
-    if (typeContainsSSEVector(RT->getDecl(), Context))
-      return 16;
-  return 0;
-}
-
 ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty,
                                             ASTContext &Context,
                                             bool ByVal) const {
-  return ABIArgInfo::getIndirect(getIndirectArgumentAlignment(Ty, Context),
-                                 ByVal);
+  if (!ByVal)
+    return ABIArgInfo::getIndirect(0, false);
+
+  // Compute the byval alignment. We trust the back-end to honor the
+  // minimum ABI alignment for byval, to make cleaner IR.
+  const unsigned MinABIAlign = 4;
+  unsigned Align = Context.getTypeAlign(Ty) / 8;
+  if (Align > MinABIAlign)
+    return ABIArgInfo::getIndirect(Align);
+  return ABIArgInfo::getIndirect(0);
 }
 
 ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
@@ -697,6 +692,10 @@
                              ASTContext &Context) const;
 
   /// getIndirectResult - Give a source type \arg Ty, return a suitable result
+  /// such that the argument will be returned in memory.
+  ABIArgInfo getIndirectReturnResult(QualType Ty, ASTContext &Context) const;
+
+  /// getIndirectResult - Give a source type \arg Ty, return a suitable result
   /// such that the argument will be passed in memory.
   ABIArgInfo getIndirectResult(QualType Ty, ASTContext &Context) const;
 
@@ -1071,6 +1070,22 @@
   return ABIArgInfo::getCoerce(CoerceTo);
 }
 
+ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty,
+                                                  ASTContext &Context) const {
+  // If this is a scalar LLVM value then assume LLVM will pass it in the right
+  // place naturally.
+  if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
+    // Treat an enum type as its underlying type.
+    if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+      Ty = EnumTy->getDecl()->getIntegerType();
+
+    return (Ty->isPromotableIntegerType() ?
+            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+  }
+
+  return ABIArgInfo::getIndirect(0);
+}
+
 ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
                                             ASTContext &Context) const {
   // If this is a scalar LLVM value then assume LLVM will pass it in the right
@@ -1084,10 +1099,16 @@
             ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
   }
 
-  bool ByVal = !isRecordWithNonTrivialDestructorOrCopyConstructor(Ty);
+  if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
+    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
 
-  // FIXME: Set alignment correctly.
-  return ABIArgInfo::getIndirect(0, ByVal);
+  // Compute the byval alignment. We trust the back-end to honor the
+  // minimum ABI alignment for byval, to make cleaner IR.
+  const unsigned MinABIAlign = 8;
+  unsigned Align = Context.getTypeAlign(Ty) / 8;
+  if (Align > MinABIAlign)
+    return ABIArgInfo::getIndirect(Align);
+  return ABIArgInfo::getIndirect(0);
 }
 
 ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
@@ -1115,7 +1136,7 @@
     // AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via
     // hidden argument.
   case Memory:
-    return getIndirectResult(RetTy, Context);
+    return getIndirectReturnResult(RetTy, Context);
 
     // AMD64-ABI 3.2.3p4: Rule 3. If the class is INTEGER, the next
     // available register of the sequence %rax, %rdx is used.

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=102019&r1=102018&r2=102019&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/x86_32-arguments.c (original)
+++ cfe/trunk/test/CodeGen/x86_32-arguments.c Wed Apr 21 14:49:55 2010
@@ -202,3 +202,15 @@
 struct s51 { vvbp f0; int f1; };
 void f51(struct s51 a0) { }
 
+// CHECK: define void @f52(%struct.s52* byval align 16 %x)
+struct s52 {
+  long double a;
+};
+void f52(struct s52 x) {}
+
+// CHECK: define void @f53(%struct.s53* byval align 32 %x)
+struct __attribute__((aligned(32))) s53 {
+  int x;
+  int y;
+};
+void f53(struct s53 x) {}

Modified: cfe/trunk/test/CodeGen/x86_64-arguments.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_64-arguments.c?rev=102019&r1=102018&r2=102019&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/x86_64-arguments.c (original)
+++ cfe/trunk/test/CodeGen/x86_64-arguments.c Wed Apr 21 14:49:55 2010
@@ -60,7 +60,7 @@
 struct s10 { int a; int b; int : 0; };
 void f10(struct s10 a0) {}
 
-// CHECK: define void @f11(%union.anon* sret %agg.result)
+// CHECK: define void @f11(%struct.s19* sret %agg.result)
 union { long double a; float b; } f11() { while (1) {} }
 
 // CHECK: define i64 @f12_0()
@@ -99,3 +99,17 @@
 struct f18_s0 { int f0; };
 void f18(int a, struct f18_s0 f18_arg1) { while (1) {} }
 
+// Check byval alignment.
+
+// CHECK: define void @f19(%struct.s19* byval align 16 %x)
+struct s19 {
+  long double a;
+};
+void f19(struct s19 x) {}
+
+// CHECK: define void @f20(%struct.s20* byval align 32 %x)
+struct __attribute__((aligned(32))) s20 {
+  int x;
+  int y;
+};
+void f20(struct s20 x) {}





More information about the cfe-commits mailing list