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