Home | History | Annotate | Download | only in CodeGen
      1 // RUN: %clang_cc1 -w -fblocks -triple i386-apple-darwin9 -target-cpu yonah -emit-llvm -o - %s | FileCheck %s
      2 
      3 // CHECK-LABEL: define signext i8 @f0()
      4 char f0(void) {
      5   return 0;
      6 }
      7 
      8 // CHECK-LABEL: define signext i16 @f1()
      9 short f1(void) {
     10   return 0;
     11 }
     12 
     13 // CHECK-LABEL: define i32 @f2()
     14 int f2(void) {
     15   return 0;
     16 }
     17 
     18 // CHECK-LABEL: define float @f3()
     19 float f3(void) {
     20   return 0;
     21 }
     22 
     23 // CHECK-LABEL: define double @f4()
     24 double f4(void) {
     25   return 0;
     26 }
     27 
     28 // CHECK-LABEL: define x86_fp80 @f5()
     29 long double f5(void) {
     30   return 0;
     31 }
     32 
     33 // CHECK-LABEL: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4)
     34 void f6(char a0, short a1, int a2, long long a3, void *a4) {}
     35 
     36 // CHECK-LABEL: define void @f7(i32 %a0)
     37 typedef enum { A, B, C } e7;
     38 void f7(e7 a0) {}
     39 
     40 // CHECK-LABEL: define i64 @f8_1()
     41 // CHECK-LABEL: define void @f8_2(i32 %a0.0, i32 %a0.1)
     42 struct s8 {
     43   int a;
     44   int b;
     45 };
     46 struct s8 f8_1(void) { while (1) {} }
     47 void f8_2(struct s8 a0) {}
     48 
     49 // This should be passed just as s8.
     50 
     51 // CHECK-LABEL: define i64 @f9_1()
     52 
     53 // FIXME: llvm-gcc expands this, this may have some value for the
     54 // backend in terms of optimization but doesn't change the ABI.
     55 // CHECK-LABEL: define void @f9_2(%struct.s9* byval align 4 %a0)
     56 struct s9 {
     57   int a : 17;
     58   int b;
     59 };
     60 struct s9 f9_1(void) { while (1) {} }
     61 void f9_2(struct s9 a0) {}
     62 
     63 // Return of small structures and unions
     64 
     65 // CHECK: float @f10()
     66 struct s10 {
     67   union { };
     68   float f;
     69 } f10(void) { while (1) {} }
     70 
     71 // Small vectors and 1 x {i64,double} are returned in registers
     72 
     73 // CHECK: i32 @f11()
     74 // CHECK: void @f12(<2 x i32>* noalias sret %agg.result)
     75 // CHECK: i64 @f13()
     76 // CHECK: i64 @f14()
     77 // CHECK: <2 x i64> @f15()
     78 // CHECK: <2 x i64> @f16()
     79 typedef short T11 __attribute__ ((vector_size (4)));
     80 T11 f11(void) { while (1) {} }
     81 typedef int T12 __attribute__ ((vector_size (8)));
     82 T12 f12(void) { while (1) {} }
     83 typedef long long T13 __attribute__ ((vector_size (8)));
     84 T13 f13(void) { while (1) {} }
     85 typedef double T14 __attribute__ ((vector_size (8)));
     86 T14 f14(void) { while (1) {} }
     87 typedef long long T15 __attribute__ ((vector_size (16)));
     88 T15 f15(void) { while (1) {} }
     89 typedef double T16 __attribute__ ((vector_size (16)));
     90 T16 f16(void) { while (1) {} }
     91 
     92 // And when the single element in a struct (but not for 64 and
     93 // 128-bits).
     94 
     95 // CHECK: i32 @f17()
     96 // CHECK: void @f18(%{{.*}}* noalias sret %agg.result)
     97 // CHECK: void @f19(%{{.*}}* noalias sret %agg.result)
     98 // CHECK: void @f20(%{{.*}}* noalias sret %agg.result)
     99 // CHECK: void @f21(%{{.*}}* noalias sret %agg.result)
    100 // CHECK: void @f22(%{{.*}}* noalias sret %agg.result)
    101 struct { T11 a; } f17(void) { while (1) {} }
    102 struct { T12 a; } f18(void) { while (1) {} }
    103 struct { T13 a; } f19(void) { while (1) {} }
    104 struct { T14 a; } f20(void) { while (1) {} }
    105 struct { T15 a; } f21(void) { while (1) {} }
    106 struct { T16 a; } f22(void) { while (1) {} }
    107 
    108 // Single element structures are handled specially
    109 
    110 // CHECK: float @f23()
    111 // CHECK: float @f24()
    112 // CHECK: float @f25()
    113 struct { float a; } f23(void) { while (1) {} }
    114 struct { float a[1]; } f24(void) { while (1) {} }
    115 struct { struct {} a; struct { float a[1]; } b; } f25(void) { while (1) {} }
    116 
    117 // Small structures are handled recursively
    118 // CHECK: i32 @f26()
    119 // CHECK: void @f27(%struct.s27* noalias sret %agg.result)
    120 struct s26 { struct { char a, b; } a; struct { char a, b; } b; } f26(void) { while (1) {} }
    121 struct s27 { struct { char a, b, c; } a; struct { char a; } b; } f27(void) { while (1) {} }
    122 
    123 // CHECK: void @f28(%struct.s28* noalias sret %agg.result)
    124 struct s28 { int a; int b[]; } f28(void) { while (1) {} }
    125 
    126 // CHECK-LABEL: define i16 @f29()
    127 struct s29 { struct { } a[1]; char b; char c; } f29(void) { while (1) {} }
    128 
    129 // CHECK-LABEL: define i16 @f30()
    130 struct s30 { char a; char b : 4; } f30(void) { while (1) {} }
    131 
    132 // CHECK-LABEL: define float @f31()
    133 struct s31 { char : 0; float b; char : 0; } f31(void) { while (1) {} }
    134 
    135 // CHECK-LABEL: define i32 @f32()
    136 struct s32 { char a; unsigned : 0; } f32(void) { while (1) {} }
    137 
    138 // CHECK-LABEL: define float @f33()
    139 struct s33 { float a; long long : 0; } f33(void) { while (1) {} }
    140 
    141 // CHECK-LABEL: define float @f34()
    142 struct s34 { struct { int : 0; } a; float b; } f34(void) { while (1) {} }
    143 
    144 // CHECK-LABEL: define i16 @f35()
    145 struct s35 { struct { int : 0; } a; char b; char c; } f35(void) { while (1) {} }
    146 
    147 // CHECK-LABEL: define i16 @f36()
    148 struct s36 { struct { int : 0; } a[2][10]; char b; char c; } f36(void) { while (1) {} }
    149 
    150 // CHECK-LABEL: define float @f37()
    151 struct s37 { float c[1][1]; } f37(void) { while (1) {} }
    152 
    153 // CHECK-LABEL: define void @f38(%struct.s38* noalias sret %agg.result)
    154 struct s38 { char a[3]; short b; } f38(void) { while (1) {} }
    155 
    156 // CHECK-LABEL: define void @f39(%struct.s39* byval align 16 %x)
    157 typedef int v39 __attribute((vector_size(16)));
    158 struct s39 { v39 x; };
    159 void f39(struct s39 x) {}
    160 
    161 // <rdar://problem/7247671>
    162 // CHECK-LABEL: define i32 @f40()
    163 enum e40 { ec0 = 0 };
    164 enum e40 f40(void) { }
    165 
    166 // CHECK-LABEL: define void ()* @f41()
    167 typedef void (^vvbp)(void);
    168 vvbp f41(void) { }
    169 
    170 // CHECK-LABEL: define i32 @f42()
    171 struct s42 { enum e40 f0; } f42(void) {  }
    172 
    173 // CHECK-LABEL: define i64 @f43()
    174 struct s43 { enum e40 f0; int f1; } f43(void) {  }
    175 
    176 // CHECK-LABEL: define void ()* @f44()
    177 struct s44 { vvbp f0; } f44(void) {  }
    178 
    179 // CHECK-LABEL: define i64 @f45()
    180 struct s45 { vvbp f0; int f1; } f45(void) {  }
    181 
    182 // CHECK-LABEL: define void @f46(i32 %a0)
    183 void f46(enum e40 a0) { }
    184 
    185 // CHECK-LABEL: define void @f47(void ()* %a1)
    186 void f47(vvbp a1) { }
    187 
    188 // CHECK-LABEL: define void @f48(i32 %a0.0)
    189 struct s48 { enum e40 f0; };
    190 void f48(struct s48 a0) { }
    191 
    192 // CHECK-LABEL: define void @f49(i32 %a0.0, i32 %a0.1)
    193 struct s49 { enum e40 f0; int f1; };
    194 void f49(struct s49 a0) { }
    195 
    196 // CHECK-LABEL: define void @f50(void ()* %a0.0)
    197 struct s50 { vvbp f0; };
    198 void f50(struct s50 a0) { }
    199 
    200 // CHECK-LABEL: define void @f51(void ()* %a0.0, i32 %a0.1)
    201 struct s51 { vvbp f0; int f1; };
    202 void f51(struct s51 a0) { }
    203 
    204 // CHECK-LABEL: define void @f52(%struct.s52* byval align 4)
    205 struct s52 {
    206   long double a;
    207 };
    208 void f52(struct s52 x) {}
    209 
    210 // CHECK-LABEL: define void @f53(%struct.s53* byval align 4)
    211 struct __attribute__((aligned(32))) s53 {
    212   int x;
    213   int y;
    214 };
    215 void f53(struct s53 x) {}
    216 
    217 typedef unsigned short v2i16 __attribute__((__vector_size__(4)));
    218 
    219 // CHECK-LABEL: define i32 @f54(i32 %arg.coerce)
    220 // rdar://8359483
    221 v2i16 f54(v2i16 arg) { return arg+arg; }
    222 
    223 
    224 typedef int v4i32 __attribute__((__vector_size__(16)));
    225 
    226 // CHECK-LABEL: define <2 x i64> @f55(<4 x i32> %arg)
    227 // PR8029
    228 v4i32 f55(v4i32 arg) { return arg+arg; }
    229 
    230 // CHECK-LABEL: define void @f56(
    231 // CHECK: i8 signext %a0, %struct.s56_0* byval align 4 %a1,
    232 // CHECK: i64 %a2.coerce, %struct.s56_1* byval align 4,
    233 // CHECK: i64 %a4.coerce, %struct.s56_2* byval align 4,
    234 // CHECK: <4 x i32> %a6, %struct.s56_3* byval align 16 %a7,
    235 // CHECK: <2 x double> %a8, %struct.s56_4* byval align 16 %a9,
    236 // CHECK: <8 x i32> %a10, %struct.s56_5* byval align 4,
    237 // CHECK: <4 x double> %a12, %struct.s56_6* byval align 4)
    238 
    239 // CHECK:   call void (i32, ...) @f56_0(i32 1,
    240 // CHECK: i32 %{{[^ ]*}}, %struct.s56_0* byval align 4 %{{[^ ]*}},
    241 // CHECK: i64 %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}},
    242 // CHECK: i64 %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}},
    243 // CHECK: <4 x i32> %{{[^ ]*}}, %struct.s56_3* byval align 16 %{{[^ ]*}},
    244 // CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 16 %{{[^ ]*}},
    245 // CHECK: <8 x i32> {{[^ ]*}}, %struct.s56_5* byval align 4 %{{[^ ]*}},
    246 // CHECK: <4 x double> {{[^ ]*}}, %struct.s56_6* byval align 4 %{{[^ ]*}})
    247 // CHECK: }
    248 //
    249 // <rdar://problem/7964854> [i386] clang misaligns long double in structures
    250 // when passed byval
    251 // <rdar://problem/8431367> clang misaligns parameters on stack
    252 typedef int __attribute__((vector_size (8))) t56_v2i;
    253 typedef double __attribute__((vector_size (8))) t56_v1d;
    254 typedef int __attribute__((vector_size (16))) t56_v4i;
    255 typedef double __attribute__((vector_size (16))) t56_v2d;
    256 typedef int __attribute__((vector_size (32))) t56_v8i;
    257 typedef double __attribute__((vector_size (32))) t56_v4d;
    258 
    259 struct s56_0 { char a; };
    260 struct s56_1 { t56_v2i a; };
    261 struct s56_2 { t56_v1d a; };
    262 struct s56_3 { t56_v4i a; };
    263 struct s56_4 { t56_v2d a; };
    264 struct s56_5 { t56_v8i a; };
    265 struct s56_6 { t56_v4d a; };
    266 
    267 void f56(char a0, struct s56_0 a1,
    268          t56_v2i a2, struct s56_1 a3,
    269          t56_v1d a4, struct s56_2 a5,
    270          t56_v4i a6, struct s56_3 a7,
    271          t56_v2d a8, struct s56_4 a9,
    272          t56_v8i a10, struct s56_5 a11,
    273          t56_v4d a12, struct s56_6 a13) {
    274   extern void f56_0(int x, ...);
    275   f56_0(1, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
    276         a10, a11, a12, a13);
    277 }
    278 
    279 // CHECK-LABEL: define void @f57(i32 %x.0, i32 %x.1)
    280 // CHECK: call void @f57(
    281 struct s57 { _Complex int x; };
    282 void f57(struct s57 x) {} void f57a(void) { f57((struct s57){1}); }
    283 
    284 // CHECK-LABEL: define void @f58()
    285 union u58 {};
    286 void f58(union u58 x) {}
    287 
    288 // CHECK-LABEL: define i64 @f59()
    289 struct s59 { float x __attribute((aligned(8))); };
    290 struct s59 f59() { while (1) {} }
    291 
    292 // CHECK-LABEL: define void @f60(%struct.s60* byval align 4, i32 %y)
    293 struct s60 { int x __attribute((aligned(8))); };
    294 void f60(struct s60 x, int y) {}
    295 
    296 // CHECK-LABEL: define void @f61(i32 %x, %struct.s61* byval align 16 %y)
    297 typedef int T61 __attribute((vector_size(16)));
    298 struct s61 { T61 x; int y; };
    299 void f61(int x, struct s61 y) {}
    300 
    301 // CHECK-LABEL: define void @f62(i32 %x, %struct.s62* byval align 4)
    302 typedef int T62 __attribute((vector_size(16)));
    303 struct s62 { T62 x; int y; } __attribute((packed, aligned(8)));
    304 void f62(int x, struct s62 y) {}
    305 
    306 // CHECK-LABEL: define i32 @f63
    307 // CHECK: ptrtoint
    308 // CHECK: and {{.*}}, -16
    309 // CHECK: inttoptr
    310 typedef int T63 __attribute((vector_size(16)));
    311 struct s63 { T63 x; int y; };
    312 int f63(int i, ...) {
    313   __builtin_va_list ap;
    314   __builtin_va_start(ap, i);
    315   struct s63 s = __builtin_va_arg(ap, struct s63);
    316   __builtin_va_end(ap);
    317   return s.y;
    318 }
    319 
    320 // CHECK-LABEL: define void @f64(%struct.s64* byval align 4 %x)
    321 struct s64 { signed char a[0]; signed char b[]; };
    322 void f64(struct s64 x) {}
    323 
    324 // CHECK-LABEL: define float @f65()
    325 struct s65 { signed char a[0]; float b; };
    326 struct s65 f65() { return (struct s65){{},2}; }
    327 
    328 // CHECK-LABEL: define <2 x i64> @f66
    329 // CHECK: ptrtoint
    330 // CHECK: and {{.*}}, -16
    331 // CHECK: inttoptr
    332 typedef int T66 __attribute((vector_size(16)));
    333 T66 f66(int i, ...) {
    334   __builtin_va_list ap;
    335   __builtin_va_start(ap, i);
    336   T66 v = __builtin_va_arg(ap, T66);
    337   __builtin_va_end(ap);
    338   return v;
    339 }
    340 
    341 // PR14453
    342 struct s67 { _Complex unsigned short int a; };
    343 void f67(struct s67 x) {}
    344 // CHECK-LABEL: define void @f67(%struct.s67* byval align 4 %x)
    345