910f0d92895e7591eb4627705b47b5734c4a6208
[lldb.git] / clang / test / CodeGenCXX / inalloca-overaligned.cpp
1 // RUN: %clang_cc1 -fms-extensions -w -triple i386-pc-win32 -emit-llvm -o - %s | FileCheck %s
2
3 // PR44395
4 // MSVC passes overaligned types indirectly since MSVC 2015. Make sure that
5 // works with inalloca.
6
7 // FIXME: Pass non-trivial *and* overaligned types indirectly. Right now the C++
8 // ABI rules say to use inalloca, and they take precedence, so it's not easy to
9 // implement this.
10
11
12 struct NonTrivial {
13   NonTrivial();
14   NonTrivial(const NonTrivial &o);
15   int x;
16 };
17
18 struct __declspec(align(64)) OverAligned {
19   OverAligned();
20   int buf[16];
21 };
22
23 extern int gvi32;
24
25 int receive_inalloca_overaligned(NonTrivial nt, OverAligned o) {
26   return nt.x + o.buf[0];
27 }
28
29 // CHECK-LABEL: define dso_local i32 @"?receive_inalloca_overaligned@@Y{{.*}}"
30 // CHECK-SAME: (<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca %0)
31
32 int pass_inalloca_overaligned() {
33   gvi32 = receive_inalloca_overaligned(NonTrivial(), OverAligned());
34   return gvi32;
35 }
36
37 // CHECK-LABEL: define dso_local i32 @"?pass_inalloca_overaligned@@Y{{.*}}"
38 // CHECK: [[TMP:%[^ ]*]] = alloca %struct.OverAligned, align 64
39 // CHECK: call i8* @llvm.stacksave()
40 // CHECK: alloca inalloca <{ %struct.NonTrivial, %struct.OverAligned* }>
41
42 // Construct OverAligned into TMP.
43 // CHECK: call x86_thiscallcc %struct.OverAligned* @"??0OverAligned@@QAE@XZ"(%struct.OverAligned* [[TMP]])
44
45 // Construct NonTrivial into the GEP.
46 // CHECK: [[GEP:%[^ ]*]] = getelementptr inbounds <{ %struct.NonTrivial, %struct.OverAligned* }>, <{ %struct.NonTrivial, %struct.OverAligned* }>* %{{.*}}, i32 0, i32 0
47 // CHECK: call x86_thiscallcc %struct.NonTrivial* @"??0NonTrivial@@QAE@XZ"(%struct.NonTrivial* [[GEP]])
48
49 // Store the address of an OverAligned temporary into the struct.
50 // CHECK: getelementptr inbounds <{ %struct.NonTrivial, %struct.OverAligned* }>, <{ %struct.NonTrivial, %struct.OverAligned* }>* %{{.*}}, i32 0, i32 1
51 // CHECK: store %struct.OverAligned* [[TMP]], %struct.OverAligned** %{{.*}}, align 4
52 // CHECK: call i32 @"?receive_inalloca_overaligned@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca %argmem)