[MS] On x86_32, pass overaligned, non-copyable arguments indirectly
[lldb.git] / clang / test / CodeGenCXX / inalloca-overaligned.cpp
index 910f0d9..83eb4d1 100644 (file)
@@ -4,11 +4,6 @@
 // MSVC passes overaligned types indirectly since MSVC 2015. Make sure that
 // works with inalloca.
 
-// FIXME: Pass non-trivial *and* overaligned types indirectly. Right now the C++
-// ABI rules say to use inalloca, and they take precedence, so it's not easy to
-// implement this.
-
-
 struct NonTrivial {
   NonTrivial();
   NonTrivial(const NonTrivial &o);
@@ -20,6 +15,12 @@ struct __declspec(align(64)) OverAligned {
   int buf[16];
 };
 
+struct __declspec(align(8)) Both {
+  Both();
+  Both(const Both &o);
+  int x, y;
+};
+
 extern int gvi32;
 
 int receive_inalloca_overaligned(NonTrivial nt, OverAligned o) {
@@ -50,3 +51,37 @@ int pass_inalloca_overaligned() {
 // CHECK: getelementptr inbounds <{ %struct.NonTrivial, %struct.OverAligned* }>, <{ %struct.NonTrivial, %struct.OverAligned* }>* %{{.*}}, i32 0, i32 1
 // CHECK: store %struct.OverAligned* [[TMP]], %struct.OverAligned** %{{.*}}, align 4
 // CHECK: call i32 @"?receive_inalloca_overaligned@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca %argmem)
+
+int receive_both(Both o) {
+  return o.x + o.y;
+}
+
+// CHECK-LABEL: define dso_local i32 @"?receive_both@@Y{{.*}}"
+// CHECK-SAME: (%struct.Both* %o)
+
+int pass_both() {
+  gvi32 = receive_both(Both());
+  return gvi32;
+}
+
+// CHECK-LABEL: define dso_local i32 @"?pass_both@@Y{{.*}}"
+// CHECK: [[TMP:%[^ ]*]] = alloca %struct.Both, align 8
+// CHECK: call x86_thiscallcc %struct.Both* @"??0Both@@QAE@XZ"(%struct.Both* [[TMP]])
+// CHECK: call i32 @"?receive_both@@Y{{.*}}"(%struct.Both* [[TMP]])
+
+int receive_inalloca_both(NonTrivial nt, Both o) {
+  return nt.x + o.x + o.y;
+}
+
+// CHECK-LABEL: define dso_local i32 @"?receive_inalloca_both@@Y{{.*}}"
+// CHECK-SAME: (<{ %struct.NonTrivial, %struct.Both* }>* inalloca %0)
+
+int pass_inalloca_both() {
+  gvi32 = receive_inalloca_both(NonTrivial(), Both());
+  return gvi32;
+}
+
+// CHECK-LABEL: define dso_local i32 @"?pass_inalloca_both@@Y{{.*}}"
+// CHECK: [[TMP:%[^ ]*]] = alloca %struct.Both, align 8
+// CHECK: call x86_thiscallcc %struct.Both* @"??0Both@@QAE@XZ"(%struct.Both* [[TMP]])
+// CHECK: call i32 @"?receive_inalloca_both@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.Both* }>* inalloca %argmem)