]> granicus.if.org Git - clang/commitdiff
When trying to pass an argument on the stack, assume LLVM will do the right
authorDaniel Dunbar <daniel@zuster.org>
Tue, 26 May 2009 16:37:37 +0000 (16:37 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 26 May 2009 16:37:37 +0000 (16:37 +0000)
thing for non-aggregate types.
 - Otherwise we unnecessarily pin values to the stack and currently end up
   triggering a backend bug in one case.

 - This loose cooperation with LLVM to implement the ABI is pretty ugly.

 - <rdar://problem/6918722> [irgen] clang miscompile of many pointer varargs on
   x86-64

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72419 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCall.cpp
test/CodeGen/x86_64-arguments.c

index ce98f8c25699a3aae29c091d500cf1f02b571689..ea0b887c64c60b1af840242d15307455ede54241 100644 (file)
@@ -571,6 +571,11 @@ class X86_64ABIInfo : public ABIInfo {
                              const llvm::Type *CoerceTo,
                              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;
+
   ABIArgInfo classifyReturnType(QualType RetTy, 
                                 ASTContext &Context) const;  
 
@@ -871,6 +876,17 @@ ABIArgInfo X86_64ABIInfo::getCoerceResult(QualType Ty,
   return ABIArgInfo::getCoerce(CoerceTo);
 }
 
+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
+  // place naturally.
+  if (!CodeGenFunction::hasAggregateLLVMType(Ty))
+    return ABIArgInfo::getDirect();
+
+  // FIXME: Set alignment correctly.
+  return ABIArgInfo::getIndirect(0);
+}
+
 ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
                                             ASTContext &Context) const {
   // AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the
@@ -895,7 +911,7 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
     // AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via
     // hidden argument.
   case Memory:
-    return ABIArgInfo::getIndirect(0);
+    return getIndirectResult(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.
@@ -991,7 +1007,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, ASTContext &Context,
     // COMPLEX_X87, it is passed in memory.
   case X87:
   case ComplexX87:
-    return ABIArgInfo::getIndirect(0);
+    return getIndirectResult(Ty, Context);
 
   case SSEUp:
   case X87Up:
@@ -1076,7 +1092,7 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context) const {
       freeIntRegs -= neededInt;
       freeSSERegs -= neededSSE;
     } else {
-      it->info = ABIArgInfo::getIndirect(0);
+      it->info = getIndirectResult(it->type, Context);
     }
   }
 }
index 3b4f5ff68fdf1679ac90e5836c70eb5e4c460688..6f7ec82872bed29f6bc09c38ee60d81e6fdd513a 100644 (file)
@@ -69,4 +69,17 @@ struct s13_0 { long long f0[3]; };
 struct s13_0 f13(int a, int b, int c, int d, 
                  struct s13_1 { long long f0[2]; } e, int f) {}
 
+// RUN: grep 'define void @f14(.*, i8 signext .X)' %t &&
+void f14(int a, int b, int c, int d, int e, int f, 
+         char X) {}
+// RUN: grep 'define void @f15(.*, i8\* .X)' %t &&
+void f15(int a, int b, int c, int d, int e, int f, 
+         void *X) {}
+// RUN: grep 'define void @f16(.*, float .X)' %t &&
+void f16(float a, float b, float c, float d, float e, float f, float g, float h,
+         float X) {}
+// RUN: grep 'define void @f17(.*, x86_fp80 .X)' %t &&
+void f17(float a, float b, float c, float d, float e, float f, float g, float h,
+         long double X) {}
+
 // RUN: true