summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp6
-rw-r--r--clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp15
2 files changed, 21 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 28312fce774..d6e86a8ecb2 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -794,6 +794,12 @@ MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
// FIXME: Implement for other architectures.
return RAA_Default;
+ case llvm::Triple::thumb:
+ // Use the simple Itanium rules for now.
+ // FIXME: This is incompatible with MSVC for arguments with a dtor and no
+ // copy ctor.
+ return !canCopyArgument(RD) ? RAA_Indirect : RAA_Default;
+
case llvm::Triple::x86:
// All record arguments are passed in memory on x86. Decide whether to
// construct the object directly in argument memory, or to construct the
diff --git a/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
index f7dc5240674..5b5d62525e2 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-linux | FileCheck -check-prefix LINUX %s
// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN32 %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=thumb-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA %s
// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN64 %s
struct Empty {};
@@ -92,6 +93,9 @@ SmallWithCtor small_with_ctor_return() { return SmallWithCtor(); }
// LINUX-LABEL: define void @_Z22small_with_ctor_returnv(%struct.SmallWithCtor* noalias sret %agg.result)
// WIN32: define void @"\01?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result)
// WIN64: define void @"\01?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result)
+// FIXME: The 'sret' mark here doesn't seem to be enough to convince LLVM to
+// preserve the hidden sret pointer in R0 across the function.
+// WOA: define arm_aapcs_vfpcc void @"\01?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result)
SmallWithVftable small_with_vftable_return() { return SmallWithVftable(); }
// LINUX-LABEL: define void @_Z25small_with_vftable_returnv(%struct.SmallWithVftable* noalias sret %agg.result)
@@ -102,6 +106,7 @@ MediumWithCopyCtor medium_with_copy_ctor_return() { return MediumWithCopyCtor();
// LINUX-LABEL: define void @_Z28medium_with_copy_ctor_returnv(%struct.MediumWithCopyCtor* noalias sret %agg.result)
// WIN32: define void @"\01?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result)
// WIN64: define void @"\01?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result)
+// WOA: define arm_aapcs_vfpcc void @"\01?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result)
// Returning a large struct that doesn't fit into a register.
Big big_return() { return Big(); }
@@ -114,22 +119,26 @@ void small_arg(Small s) {}
// LINUX-LABEL: define void @_Z9small_arg5Small(i32 %s.0)
// WIN32: define void @"\01?small_arg@@YAXUSmall@@@Z"(i32 %s.0)
// WIN64: define void @"\01?small_arg@@YAXUSmall@@@Z"(i32 %s.coerce)
+// WOA: define arm_aapcs_vfpcc void @"\01?small_arg@@YAXUSmall@@@Z"([1 x i32] %s.coerce)
void medium_arg(Medium s) {}
// LINUX-LABEL: define void @_Z10medium_arg6Medium(i32 %s.0, i32 %s.1)
// WIN32: define void @"\01?medium_arg@@YAXUMedium@@@Z"(i32 %s.0, i32 %s.1)
// WIN64: define void @"\01?medium_arg@@YAXUMedium@@@Z"(i64 %s.coerce)
+// WOA: define arm_aapcs_vfpcc void @"\01?medium_arg@@YAXUMedium@@@Z"([2 x i32] %s.coerce)
void small_arg_with_ctor(SmallWithCtor s) {}
// LINUX-LABEL: define void @_Z19small_arg_with_ctor13SmallWithCtor(%struct.SmallWithCtor* byval align 4 %s)
// WIN32: define void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(i32 %s.0)
// WIN64: define void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(i32 %s.coerce)
+// WOA: define arm_aapcs_vfpcc void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"([1 x i32] %s.coerce)
// FIXME: We could coerce to a series of i32s here if we wanted to.
void multibyte_arg(Multibyte s) {}
// LINUX-LABEL: define void @_Z13multibyte_arg9Multibyte(%struct.Multibyte* byval align 4 %s)
// WIN32: define void @"\01?multibyte_arg@@YAXUMultibyte@@@Z"(%struct.Multibyte* byval align 4 %s)
// WIN64: define void @"\01?multibyte_arg@@YAXUMultibyte@@@Z"(i32 %s.coerce)
+// WOA: define arm_aapcs_vfpcc void @"\01?multibyte_arg@@YAXUMultibyte@@@Z"([1 x i32] %s.coerce)
void packed_arg(Packed s) {}
// LINUX-LABEL: define void @_Z10packed_arg6Packed(%struct.Packed* byval align 4 %s)
@@ -145,6 +154,11 @@ void small_arg_with_dtor(SmallWithDtor s) {}
// WIN64: call void @"\01??1SmallWithDtor@@QEAA@XZ"
// WIN64: }
+// FIXME: MSVC incompatible!
+// WOA: define arm_aapcs_vfpcc void @"\01?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(%struct.SmallWithDtor* %s) {{.*}} {
+// WOA: call arm_aapcs_vfpcc void @"\01??1SmallWithDtor@@QAA@XZ"(%struct.SmallWithDtor* %s)
+// WOA: }
+
void call_small_arg_with_dtor() {
small_arg_with_dtor(SmallWithDtor());
}
@@ -211,6 +225,7 @@ void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {}
// LINUX-LABEL: define void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* %s)
// WIN32: define void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ %struct.MediumWithCopyCtor }>* inalloca)
// WIN64: define void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
+// WOA: define arm_aapcs_vfpcc void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
void big_arg(Big s) {}
// LINUX-LABEL: define void @_Z7big_arg3Big(%struct.Big* byval align 4 %s)
OpenPOWER on IntegriCloud