summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Kuperstein <michael.m.kuperstein@intel.com>2015-02-24 09:35:58 +0000
committerMichael Kuperstein <michael.m.kuperstein@intel.com>2015-02-24 09:35:58 +0000
commit4f818708a808d52bca8cf8bdb79a9595268f22bd (patch)
tree1485c088a9f7c82c5274d9baef215c4ccdb27fc2
parent7906f139c3adf797c8f1a8ec3a287682dec0176b (diff)
downloadbcm5719-llvm-4f818708a808d52bca8cf8bdb79a9595268f22bd.tar.gz
bcm5719-llvm-4f818708a808d52bca8cf8bdb79a9595268f22bd.zip
[WinX86_64 ABI] Treat C99 _Complex as a struct
MSVC does not support C99 _Complex. ICC, however, does support it on windows x86_64, and treats it, for purposes of parameter passing, as equivalent to a struct containing two fields (for the real and imaginary part). Differential Revision: http://reviews.llvm.org/D7825 llvm-svn: 230315
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp2
-rw-r--r--clang/test/CodeGen/x86_64-arguments-win32.c15
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; }
OpenPOWER on IntegriCloud