1c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC
2c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// RUN: %clang_cc1 -mfloat-abi hard -triple armv7-unknown-linux-gnueabi -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM32
3c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// RUN: %clang_cc1 -mfloat-abi hard -triple aarch64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM64
4c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// RUN: %clang_cc1 -mfloat-abi hard -triple x86_64-unknown-windows-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=X64
5c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
6c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry#if defined(__x86_64__)
7c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry#define CC __attribute__((vectorcall))
8c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry#else
9c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry#define CC
10c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry#endif
11c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
12c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// Test that C++ classes are correctly classified as homogeneous aggregates.
13c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
14c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct Base1 {
15c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry  int x;
16c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry};
17c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct Base2 {
18c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry  double x;
19c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry};
20c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct Base3 {
21c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry  double x;
22c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry};
23c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct D1 : Base1 {  // non-homogeneous aggregate
24c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry  double y, z;
25c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry};
26c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct D2 : Base2 {  // homogeneous aggregate
27c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry  double y, z;
28c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry};
29c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct D3 : Base1, Base2 {  // non-homogeneous aggregate
30c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry  double y, z;
31c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry};
32c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct D4 : Base2, Base3 {  // homogeneous aggregate
33c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry  double y, z;
34c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry};
35c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
36c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct I1 : Base2 {};
37c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct I2 : Base2 {};
38c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct I3 : Base2 {};
39c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct D5 : I1, I2, I3 {}; // homogeneous aggregate
40c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
41c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// PPC: define void @_Z7func_D12D1(%struct.D1* noalias sret %agg.result, [3 x i64] %x.coerce)
42c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM32: define arm_aapcs_vfpcc void @_Z7func_D12D1(%struct.D1* noalias sret %agg.result, [3 x i64] %x.coerce)
43c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM64: define void @_Z7func_D12D1(%struct.D1* noalias sret %agg.result, %struct.D1* %x)
44c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// X64: define x86_vectorcallcc void @"\01_Z7func_D12D1@@24"(%struct.D1* noalias sret %agg.result, %struct.D1* %x)
45c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryD1 CC func_D1(D1 x) { return x; }
46c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
47c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// PPC: define [3 x double] @_Z7func_D22D2([3 x double] %x.coerce)
48c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM32: define arm_aapcs_vfpcc %struct.D2 @_Z7func_D22D2(%struct.D2 %x.coerce)
49c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM64: define %struct.D2 @_Z7func_D22D2([3 x double] %x.coerce)
50c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// X64: define x86_vectorcallcc %struct.D2 @"\01_Z7func_D22D2@@24"(double %x.0, double %x.1, double %x.2)
51c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryD2 CC func_D2(D2 x) { return x; }
52c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
53c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// PPC: define void @_Z7func_D32D3(%struct.D3* noalias sret %agg.result, [4 x i64] %x.coerce)
54c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM32: define arm_aapcs_vfpcc void @_Z7func_D32D3(%struct.D3* noalias sret %agg.result, [4 x i64] %x.coerce)
55c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM64: define void @_Z7func_D32D3(%struct.D3* noalias sret %agg.result, %struct.D3* %x)
56c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryD3 CC func_D3(D3 x) { return x; }
57c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
58c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// PPC: define [4 x double] @_Z7func_D42D4([4 x double] %x.coerce)
59c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM32: define arm_aapcs_vfpcc %struct.D4 @_Z7func_D42D4(%struct.D4 %x.coerce)
60c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM64: define %struct.D4 @_Z7func_D42D4([4 x double] %x.coerce)
61c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryD4 CC func_D4(D4 x) { return x; }
62c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
63c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryD5 CC func_D5(D5 x) { return x; }
64c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// PPC: define [3 x double] @_Z7func_D52D5([3 x double] %x.coerce)
65c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM32: define arm_aapcs_vfpcc %struct.D5 @_Z7func_D52D5(%struct.D5 %x.coerce)
66c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
67c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// The C++ multiple inheritance expansion case is a little more complicated, so
68c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// do some extra checking.
69c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry//
70c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM64-LABEL: define %struct.D5 @_Z7func_D52D5([3 x double] %x.coerce)
71c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM64: bitcast %struct.D5* %{{.*}} to [3 x double]*
72c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM64: store [3 x double] %x.coerce, [3 x double]*
73c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
74c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryvoid call_D5(D5 *p) {
75c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry  func_D5(*p);
76c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}
77c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
78c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// Check the call site.
79c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry//
80c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM64-LABEL: define void @_Z7call_D5P2D5(%struct.D5* %p)
81c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM64: load [3 x double], [3 x double]*
82c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM64: call %struct.D5 @_Z7func_D52D5([3 x double] %{{.*}})
83c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
84c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct Empty { };
85c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct Float1 { float x; };
86c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct Float2 { float y; };
87c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct HVAWithEmptyBase : Float1, Empty, Float2 { float z; };
88c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
89c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// PPC: define void @_Z15with_empty_base16HVAWithEmptyBase([3 x float] %a.coerce)
90c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM64: define void @_Z15with_empty_base16HVAWithEmptyBase([3 x float] %a.coerce)
91c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM32: define arm_aapcs_vfpcc void @_Z15with_empty_base16HVAWithEmptyBase(%struct.HVAWithEmptyBase %a.coerce)
92c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryvoid CC with_empty_base(HVAWithEmptyBase a) {}
93c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
94c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// FIXME: MSVC doesn't consider this an HVA because of the empty base.
95c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// X64: define x86_vectorcallcc void @"\01_Z15with_empty_base16HVAWithEmptyBase@@16"(float %a.0, float %a.1, float %a.2)
96c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
97c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystruct HVAWithEmptyBitField : Float1, Float2 {
98c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry  int : 0; // Takes no space.
99c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry  float z;
100c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry};
101c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry
102c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// PPC: define void @_Z19with_empty_bitfield20HVAWithEmptyBitField([3 x float] %a.coerce)
103c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM64: define void @_Z19with_empty_bitfield20HVAWithEmptyBitField([3 x float] %a.coerce)
104c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// ARM32: define arm_aapcs_vfpcc void @_Z19with_empty_bitfield20HVAWithEmptyBitField(%struct.HVAWithEmptyBitField %a.coerce)
105c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry// X64: define x86_vectorcallcc void @"\01_Z19with_empty_bitfield20HVAWithEmptyBitField@@16"(float %a.0, float %a.1, float %a.2)
106c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryvoid CC with_empty_bitfield(HVAWithEmptyBitField a) {}
107c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry