diff options
| -rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 2 | ||||
| -rw-r--r-- | clang/test/CodeGen/x86_64-arguments-win32.c | 15 | 
2 files changed, 16 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 814a0b4eb09..4b16fe8bdd0 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -3041,7 +3041,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, unsigned &FreeSSERegs,        return ABIArgInfo::getDirect();    } -  if (RT || Ty->isMemberPointerType()) { +  if (RT || Ty->isAnyComplexType() || Ty->isMemberPointerType()) {      // MS x64 ABI requirement: "Any argument that doesn't fit in 8 bytes, or is      // not 1, 2, 4, or 8 bytes, must be passed by reference."      if (Width > 64 || !llvm::isPowerOf2_64(Width)) diff --git a/clang/test/CodeGen/x86_64-arguments-win32.c b/clang/test/CodeGen/x86_64-arguments-win32.c index 5aea7fc6236..7731eadd01e 100644 --- a/clang/test/CodeGen/x86_64-arguments-win32.c +++ b/clang/test/CodeGen/x86_64-arguments-win32.c @@ -14,3 +14,18 @@ void f3(short a) {}  // CHECK-LABEL: define void @f4(i16 %a)  void f4(unsigned short a) {} + +// For ABI compatibility with ICC, _Complex should be passed/returned +// as if it were a struct with two elements. + +// CHECK-LABEL: define void @f5(i64 %a.coerce) +void f5(_Complex float a) {} + +// CHECK-LABEL: define void @f6({ double, double }* %a) +void f6(_Complex double a) {} + +// CHECK-LABEL: define i64 @f7() +_Complex float f7() { return 1.0; } + +// CHECK-LABEL: define void @f8({ double, double }* noalias sret %agg.result) +_Complex double f8() { return 1.0; }  | 

