1 // RUN: %clang_cc1 -triple armv7---eabi -target-abi aapcs -mfloat-abi hard -emit-llvm %s -o - | FileCheck %s 2 #include <stdint.h> 3 4 /* This is not a homogenous aggregate - fundamental types are different */ 5 typedef union { 6 float f[4]; 7 uint32_t i[4]; 8 } union_with_first_floats; 9 union_with_first_floats g_u_f; 10 11 extern void takes_union_with_first_floats(union_with_first_floats a); 12 extern union_with_first_floats returns_union_with_first_floats(void); 13 14 void test_union_with_first_floats(void) { 15 takes_union_with_first_floats(g_u_f); 16 } 17 // CHECK: declare arm_aapcs_vfpcc void @takes_union_with_first_floats([4 x i32]) 18 19 void test_return_union_with_first_floats(void) { 20 g_u_f = returns_union_with_first_floats(); 21 } 22 // CHECK: declare arm_aapcs_vfpcc void @returns_union_with_first_floats(%union.union_with_first_floats* sret) 23 24 /* This is not a homogenous aggregate - fundamental types are different */ 25 typedef union { 26 uint32_t i[4]; 27 float f[4]; 28 } union_with_non_first_floats; 29 union_with_non_first_floats g_u_nf_f; 30 31 extern void takes_union_with_non_first_floats(union_with_non_first_floats a); 32 extern union_with_non_first_floats returns_union_with_non_first_floats(void); 33 34 void test_union_with_non_first_floats(void) { 35 takes_union_with_non_first_floats(g_u_nf_f); 36 } 37 // CHECK: declare arm_aapcs_vfpcc void @takes_union_with_non_first_floats([4 x i32]) 38 39 void test_return_union_with_non_first_floats(void) { 40 g_u_nf_f = returns_union_with_non_first_floats(); 41 } 42 // CHECK: declare arm_aapcs_vfpcc void @returns_union_with_non_first_floats(%union.union_with_non_first_floats* sret) 43 44 /* This is not a homogenous aggregate - fundamental types are different */ 45 typedef struct { 46 float a; 47 union_with_first_floats b; 48 } struct_with_union_with_first_floats; 49 struct_with_union_with_first_floats g_s_f; 50 51 extern void takes_struct_with_union_with_first_floats(struct_with_union_with_first_floats a); 52 extern struct_with_union_with_first_floats returns_struct_with_union_with_first_floats(void); 53 54 void test_struct_with_union_with_first_floats(void) { 55 takes_struct_with_union_with_first_floats(g_s_f); 56 } 57 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_first_floats([5 x i32]) 58 59 void test_return_struct_with_union_with_first_floats(void) { 60 g_s_f = returns_struct_with_union_with_first_floats(); 61 } 62 // CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_first_floats(%struct.struct_with_union_with_first_floats* sret) 63 64 /* This is not a homogenous aggregate - fundamental types are different */ 65 typedef struct { 66 float a; 67 union_with_non_first_floats b; 68 } struct_with_union_with_non_first_floats; 69 struct_with_union_with_non_first_floats g_s_nf_f; 70 71 extern void takes_struct_with_union_with_non_first_floats(struct_with_union_with_non_first_floats a); 72 extern struct_with_union_with_non_first_floats returns_struct_with_union_with_non_first_floats(void); 73 74 void test_struct_with_union_with_non_first_floats(void) { 75 takes_struct_with_union_with_non_first_floats(g_s_nf_f); 76 } 77 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_non_first_floats([5 x i32]) 78 79 void test_return_struct_with_union_with_non_first_floats(void) { 80 g_s_nf_f = returns_struct_with_union_with_non_first_floats(); 81 } 82 // CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_non_first_floats(%struct.struct_with_union_with_non_first_floats* sret) 83 84 /* Plain array is not a homogenous aggregate */ 85 extern void takes_array_of_floats(float a[4]); 86 void test_array_of_floats(void) { 87 float a[4] = {1.0, 2.0, 3.0, 4.0}; 88 takes_array_of_floats(a); 89 } 90 // CHECK: declare arm_aapcs_vfpcc void @takes_array_of_floats(float*) 91 92 /* Struct-type homogenous aggregate */ 93 typedef struct { 94 float x, y, z, w; 95 } struct_with_fundamental_elems; 96 struct_with_fundamental_elems g_s; 97 98 extern void takes_struct_with_fundamental_elems(struct_with_fundamental_elems a); 99 extern struct_with_fundamental_elems returns_struct_with_fundamental_elems(void); 100 101 void test_struct_with_fundamental_elems(void) { 102 takes_struct_with_fundamental_elems(g_s); 103 // CHECK: call arm_aapcs_vfpcc void @takes_struct_with_fundamental_elems(float {{.*}}, float {{.*}}, float{{.*}}, float {{.*}}) 104 } 105 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_fundamental_elems(float, float, float, float) 106 107 void test_return_struct_with_fundamental_elems(void) { 108 g_s = returns_struct_with_fundamental_elems(); 109 // CHECK: call arm_aapcs_vfpcc %struct.struct_with_fundamental_elems @returns_struct_with_fundamental_elems() 110 } 111 // CHECK: declare arm_aapcs_vfpcc %struct.struct_with_fundamental_elems @returns_struct_with_fundamental_elems() 112 113 /* Array-type homogenous aggregate */ 114 typedef struct { 115 float xyzw[4]; 116 } struct_with_array; 117 struct_with_array g_s_a; 118 119 extern void takes_struct_with_array(struct_with_array a); 120 extern struct_with_array returns_struct_with_array(void); 121 122 void test_struct_with_array(void) { 123 takes_struct_with_array(g_s_a); 124 // CHECK: call arm_aapcs_vfpcc void @takes_struct_with_array(float {{.*}}, float {{.*}}, float {{.*}}, float {{.*}}) 125 } 126 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_array(float, float, float, float) 127 128 void test_return_struct_with_array(void) { 129 g_s_a = returns_struct_with_array(); 130 // CHECK: call arm_aapcs_vfpcc %struct.struct_with_array @returns_struct_with_array() 131 } 132 // CHECK: declare arm_aapcs_vfpcc %struct.struct_with_array @returns_struct_with_array() 133 134 /* This union is a homogenous aggregate. Check that it's passed properly */ 135 typedef union { 136 struct_with_fundamental_elems xyzw; 137 float a[3]; 138 } union_with_struct_with_fundamental_elems; 139 union_with_struct_with_fundamental_elems g_u_s_fe; 140 141 extern void takes_union_with_struct_with_fundamental_elems(union_with_struct_with_fundamental_elems a); 142 extern union_with_struct_with_fundamental_elems returns_union_with_struct_with_fundamental_elems(void); 143 144 void test_union_with_struct_with_fundamental_elems(void) { 145 takes_union_with_struct_with_fundamental_elems(g_u_s_fe); 146 // CHECK: call arm_aapcs_vfpcc void @takes_union_with_struct_with_fundamental_elems(float {{.*}}, float {{.*}}, float {{.*}}, float {{.*}}) 147 } 148 // CHECK: declare arm_aapcs_vfpcc void @takes_union_with_struct_with_fundamental_elems(float, float, float, float) 149 150 void test_return_union_with_struct_with_fundamental_elems(void) { 151 g_u_s_fe = returns_union_with_struct_with_fundamental_elems(); 152 // CHECK: call arm_aapcs_vfpcc %union.union_with_struct_with_fundamental_elems @returns_union_with_struct_with_fundamental_elems() 153 } 154 // CHECK: declare arm_aapcs_vfpcc %union.union_with_struct_with_fundamental_elems @returns_union_with_struct_with_fundamental_elems() 155 156 // FIXME: Tests necessary: 157 // - Vectors 158 // - C++ stuff