Home | History | Annotate | Download | only in CodeGen
      1 // REQUIRES: arm-registered-target
      2 // RUN: %clang_cc1 -triple armv7---eabi -target-abi aapcs -mfloat-abi hard -emit-llvm %s -o - | FileCheck %s
      3 
      4 typedef long long int64_t;
      5 typedef unsigned int uint32_t;
      6 
      7 /* This is not a homogenous aggregate - fundamental types are different */
      8 typedef union {
      9   float       f[4];
     10   uint32_t    i[4];
     11 } union_with_first_floats;
     12 union_with_first_floats g_u_f;
     13 
     14 extern void takes_union_with_first_floats(union_with_first_floats a);
     15 extern union_with_first_floats returns_union_with_first_floats(void);
     16 
     17 void test_union_with_first_floats(void) {
     18   takes_union_with_first_floats(g_u_f);
     19 }
     20 // CHECK: declare arm_aapcs_vfpcc void @takes_union_with_first_floats([4 x i32])
     21 
     22 void test_return_union_with_first_floats(void) {
     23   g_u_f = returns_union_with_first_floats();
     24 }
     25 // CHECK: declare arm_aapcs_vfpcc void @returns_union_with_first_floats(%union.union_with_first_floats* sret)
     26 
     27 /* This is not a homogenous aggregate - fundamental types are different */
     28 typedef union {
     29     uint32_t    i[4];
     30     float       f[4];
     31 } union_with_non_first_floats;
     32 union_with_non_first_floats g_u_nf_f;
     33 
     34 extern void takes_union_with_non_first_floats(union_with_non_first_floats a);
     35 extern union_with_non_first_floats returns_union_with_non_first_floats(void);
     36 
     37 void test_union_with_non_first_floats(void) {
     38   takes_union_with_non_first_floats(g_u_nf_f);
     39 }
     40 // CHECK: declare arm_aapcs_vfpcc void @takes_union_with_non_first_floats([4 x i32])
     41 
     42 void test_return_union_with_non_first_floats(void) {
     43   g_u_nf_f = returns_union_with_non_first_floats();
     44 }
     45 // CHECK: declare arm_aapcs_vfpcc void @returns_union_with_non_first_floats(%union.union_with_non_first_floats* sret)
     46 
     47 /* This is not a homogenous aggregate - fundamental types are different */
     48 typedef struct {
     49   float a;
     50   union_with_first_floats b;
     51 } struct_with_union_with_first_floats;
     52 struct_with_union_with_first_floats g_s_f;
     53 
     54 extern void takes_struct_with_union_with_first_floats(struct_with_union_with_first_floats a);
     55 extern struct_with_union_with_first_floats returns_struct_with_union_with_first_floats(void);
     56 
     57 void test_struct_with_union_with_first_floats(void) {
     58   takes_struct_with_union_with_first_floats(g_s_f);
     59 }
     60 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_first_floats([5 x i32])
     61 
     62 void test_return_struct_with_union_with_first_floats(void) {
     63   g_s_f = returns_struct_with_union_with_first_floats();
     64 }
     65 // CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_first_floats(%struct.struct_with_union_with_first_floats* sret)
     66 
     67 /* This is not a homogenous aggregate - fundamental types are different */
     68 typedef struct {
     69   float a;
     70   union_with_non_first_floats b;
     71 } struct_with_union_with_non_first_floats;
     72 struct_with_union_with_non_first_floats g_s_nf_f;
     73 
     74 extern void takes_struct_with_union_with_non_first_floats(struct_with_union_with_non_first_floats a);
     75 extern struct_with_union_with_non_first_floats returns_struct_with_union_with_non_first_floats(void);
     76 
     77 void test_struct_with_union_with_non_first_floats(void) {
     78   takes_struct_with_union_with_non_first_floats(g_s_nf_f);
     79 }
     80 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_non_first_floats([5 x i32])
     81 
     82 void test_return_struct_with_union_with_non_first_floats(void) {
     83   g_s_nf_f = returns_struct_with_union_with_non_first_floats();
     84 }
     85 // CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_non_first_floats(%struct.struct_with_union_with_non_first_floats* sret)
     86 
     87 /* Plain array is not a homogenous aggregate */
     88 extern void takes_array_of_floats(float a[4]);
     89 void test_array_of_floats(void) {
     90   float a[4] = {1.0, 2.0, 3.0, 4.0};
     91   takes_array_of_floats(a);
     92 }
     93 // CHECK: declare arm_aapcs_vfpcc void @takes_array_of_floats(float*)
     94 
     95 /* Struct-type homogenous aggregate */
     96 typedef struct {
     97   float x, y, z, w;
     98 } struct_with_fundamental_elems;
     99 struct_with_fundamental_elems g_s;
    100 
    101 extern void takes_struct_with_fundamental_elems(struct_with_fundamental_elems a);
    102 extern struct_with_fundamental_elems returns_struct_with_fundamental_elems(void);
    103 
    104 void test_struct_with_fundamental_elems(void) {
    105   takes_struct_with_fundamental_elems(g_s);
    106 // CHECK:  call arm_aapcs_vfpcc  void @takes_struct_with_fundamental_elems(float {{.*}}, float {{.*}}, float{{.*}}, float {{.*}})
    107 }
    108 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_fundamental_elems(float, float, float, float)
    109 
    110 void test_return_struct_with_fundamental_elems(void) {
    111   g_s = returns_struct_with_fundamental_elems();
    112 // CHECK: call arm_aapcs_vfpcc  %struct.struct_with_fundamental_elems @returns_struct_with_fundamental_elems()
    113 }
    114 // CHECK: declare arm_aapcs_vfpcc %struct.struct_with_fundamental_elems @returns_struct_with_fundamental_elems()
    115 
    116 /* Array-type homogenous aggregate */
    117 typedef struct {
    118   float xyzw[4];
    119 } struct_with_array;
    120 struct_with_array g_s_a;
    121 
    122 extern void takes_struct_with_array(struct_with_array a);
    123 extern struct_with_array returns_struct_with_array(void);
    124 
    125 void test_struct_with_array(void) {
    126   takes_struct_with_array(g_s_a);
    127 // CHECK:   call arm_aapcs_vfpcc  void @takes_struct_with_array(float {{.*}}, float {{.*}}, float {{.*}}, float {{.*}})
    128 }
    129 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_array(float, float, float, float)
    130 
    131 void test_return_struct_with_array(void) {
    132   g_s_a = returns_struct_with_array();
    133 // CHECK:   call arm_aapcs_vfpcc  %struct.struct_with_array @returns_struct_with_array()
    134 }
    135 // CHECK: declare arm_aapcs_vfpcc %struct.struct_with_array @returns_struct_with_array()
    136 
    137 /* This union is a homogenous aggregate. Check that it's passed properly */
    138 typedef union {
    139   struct_with_fundamental_elems xyzw;
    140   float a[3];
    141 } union_with_struct_with_fundamental_elems;
    142 union_with_struct_with_fundamental_elems g_u_s_fe;
    143 
    144 extern void takes_union_with_struct_with_fundamental_elems(union_with_struct_with_fundamental_elems a);
    145 extern union_with_struct_with_fundamental_elems returns_union_with_struct_with_fundamental_elems(void);
    146 
    147 void test_union_with_struct_with_fundamental_elems(void) {
    148   takes_union_with_struct_with_fundamental_elems(g_u_s_fe);
    149 // CHECK: call arm_aapcs_vfpcc  void @takes_union_with_struct_with_fundamental_elems(float {{.*}}, float {{.*}}, float {{.*}}, float {{.*}})
    150 }
    151 // CHECK: declare arm_aapcs_vfpcc void @takes_union_with_struct_with_fundamental_elems(float, float, float, float)
    152 
    153 void test_return_union_with_struct_with_fundamental_elems(void) {
    154   g_u_s_fe = returns_union_with_struct_with_fundamental_elems();
    155 // CHECK: call arm_aapcs_vfpcc  %union.union_with_struct_with_fundamental_elems @returns_union_with_struct_with_fundamental_elems()
    156 }
    157 // CHECK: declare arm_aapcs_vfpcc %union.union_with_struct_with_fundamental_elems @returns_union_with_struct_with_fundamental_elems()
    158 
    159 // Make sure HAs that can be partially fit into VFP registers will be allocated
    160 // on stack and that later VFP candidates will go on stack as well.
    161 typedef struct {
    162   double x;
    163   double a2;
    164   double a3;
    165   double a4;
    166 } struct_of_four_doubles;
    167 extern void takes_struct_of_four_doubles(double a, struct_of_four_doubles b, struct_of_four_doubles c, double d);
    168 struct_of_four_doubles g_s4d;
    169 
    170 void test_struct_of_four_doubles(void) {
    171 // CHECK: test_struct_of_four_doubles
    172 // CHECK: call arm_aapcs_vfpcc void @takes_struct_of_four_doubles(double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [6 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}})
    173   takes_struct_of_four_doubles(3.0, g_s4d, g_s4d, 4.0);
    174 }
    175 
    176 extern void takes_struct_with_backfill(float f1, double a, float f2, struct_of_four_doubles b, struct_of_four_doubles c, double d);
    177 void test_struct_with_backfill(void) {
    178 // CHECK: test_struct_with_backfill
    179 // CHECK: call arm_aapcs_vfpcc void @takes_struct_with_backfill(float {{.*}}, double {{.*}}, float {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [4 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}})
    180   takes_struct_with_backfill(3.0, 3.1, 3.2, g_s4d, g_s4d, 4.0);
    181 }
    182 
    183 typedef __attribute__(( ext_vector_type(8) )) char __char8;
    184 typedef __attribute__(( ext_vector_type(4) ))  short __short4;
    185 typedef struct {
    186   __char8  a1;
    187   __short4 a2;
    188   __char8  a3;
    189   __short4 a4;
    190 } struct_of_vecs;
    191 extern void takes_struct_of_vecs(double a, struct_of_vecs b, struct_of_vecs c, double d);
    192 struct_of_vecs g_vec;
    193 
    194 void test_struct_of_vecs(void) {
    195 // CHECK: test_struct_of_vecs
    196 // CHECK: call arm_aapcs_vfpcc void @takes_struct_of_vecs(double {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, [6 x float] undef, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, double {{.*}})
    197   takes_struct_of_vecs(3.0, g_vec, g_vec, 4.0);
    198 }
    199 
    200 // FIXME: Tests necessary:
    201 //         - Vectors
    202 //         - C++ stuff
    203