Home | History | Annotate | Download | only in CodeGen
      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