diff options
| author | Daniel Dunbar <daniel@zuster.org> | 2009-05-26 16:37:37 +0000 |
|---|---|---|
| committer | Daniel Dunbar <daniel@zuster.org> | 2009-05-26 16:37:37 +0000 |
| commit | 1518b64ddcc01a8f8b9c4769e89dd09ec9391f95 (patch) | |
| tree | 840048b96b9fa37467e397382335ac488d6f8686 | |
| parent | f7323f3f65ed9df4ce8c06d5964b739f8c80999a (diff) | |
| download | bcm5719-llvm-1518b64ddcc01a8f8b9c4769e89dd09ec9391f95.tar.gz bcm5719-llvm-1518b64ddcc01a8f8b9c4769e89dd09ec9391f95.zip | |
When trying to pass an argument on the stack, assume LLVM will do the right
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
llvm-svn: 72419
| -rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 22 | ||||
| -rw-r--r-- | clang/test/CodeGen/x86_64-arguments.c | 13 |
2 files changed, 32 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index ce98f8c2569..ea0b887c64c 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -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); } } } diff --git a/clang/test/CodeGen/x86_64-arguments.c b/clang/test/CodeGen/x86_64-arguments.c index 3b4f5ff68fd..6f7ec82872b 100644 --- a/clang/test/CodeGen/x86_64-arguments.c +++ b/clang/test/CodeGen/x86_64-arguments.c @@ -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 |

