1 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s| FileCheck %s 2 #include <stdarg.h> 3 4 // CHECK: define signext i8 @f0() 5 char f0(void) { 6 return 0; 7 } 8 9 // CHECK: define signext i16 @f1() 10 short f1(void) { 11 return 0; 12 } 13 14 // CHECK: define i32 @f2() 15 int f2(void) { 16 return 0; 17 } 18 19 // CHECK: define float @f3() 20 float f3(void) { 21 return 0; 22 } 23 24 // CHECK: define double @f4() 25 double f4(void) { 26 return 0; 27 } 28 29 // CHECK: define x86_fp80 @f5() 30 long double f5(void) { 31 return 0; 32 } 33 34 // CHECK: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4) 35 void f6(char a0, short a1, int a2, long long a3, void *a4) { 36 } 37 38 // CHECK: define void @f7(i32 %a0) 39 typedef enum { A, B, C } e7; 40 void f7(e7 a0) { 41 } 42 43 // Test merging/passing of upper eightbyte with X87 class. 44 // 45 // CHECK: define void @f8_1(%union.u8* noalias sret %agg.result) 46 // CHECK: define void @f8_2(%union.u8* byval align 16 %a0) 47 union u8 { 48 long double a; 49 int b; 50 }; 51 union u8 f8_1() { while (1) {} } 52 void f8_2(union u8 a0) {} 53 54 // CHECK: define i64 @f9() 55 struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} } 56 57 // CHECK: define void @f10(i64 %a0.coerce) 58 struct s10 { int a; int b; int : 0; }; 59 void f10(struct s10 a0) {} 60 61 // CHECK: define void @f11(%union.anon* noalias sret %agg.result) 62 union { long double a; float b; } f11() { while (1) {} } 63 64 // CHECK: define i32 @f12_0() 65 // CHECK: define void @f12_1(i32 %a0.coerce) 66 struct s12 { int a __attribute__((aligned(16))); }; 67 struct s12 f12_0(void) { while (1) {} } 68 void f12_1(struct s12 a0) {} 69 70 // Check that sret parameter is accounted for when checking available integer 71 // registers. 72 // CHECK: define void @f13(%struct.s13_0* noalias sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, {{.*}}* byval align 8 %e, i32 %f) 73 74 struct s13_0 { long long f0[3]; }; 75 struct s13_1 { long long f0[2]; }; 76 struct s13_0 f13(int a, int b, int c, int d, 77 struct s13_1 e, int f) { while (1) {} } 78 79 // CHECK: define void @f14({{.*}}, i8 signext %X) 80 void f14(int a, int b, int c, int d, int e, int f, char X) {} 81 82 // CHECK: define void @f15({{.*}}, i8* %X) 83 void f15(int a, int b, int c, int d, int e, int f, void *X) {} 84 85 // CHECK: define void @f16({{.*}}, float %X) 86 void f16(float a, float b, float c, float d, float e, float f, float g, float h, 87 float X) {} 88 89 // CHECK: define void @f17({{.*}}, x86_fp80 %X) 90 void f17(float a, float b, float c, float d, float e, float f, float g, float h, 91 long double X) {} 92 93 // Check for valid coercion. The struct should be passed/returned as i32, not 94 // as i64 for better code quality. 95 // rdar://8135035 96 // CHECK: define void @f18(i32 %a, i32 %f18_arg1.coerce) 97 struct f18_s0 { int f0; }; 98 void f18(int a, struct f18_s0 f18_arg1) { while (1) {} } 99 100 // Check byval alignment. 101 102 // CHECK: define void @f19(%struct.s19* byval align 16 %x) 103 struct s19 { 104 long double a; 105 }; 106 void f19(struct s19 x) {} 107 108 // CHECK: define void @f20(%struct.s20* byval align 32 %x) 109 struct __attribute__((aligned(32))) s20 { 110 int x; 111 int y; 112 }; 113 void f20(struct s20 x) {} 114 115 struct StringRef { 116 long x; 117 const char *Ptr; 118 }; 119 120 // rdar://7375902 121 // CHECK: define i8* @f21(i64 %S.coerce0, i8* %S.coerce1) 122 const char *f21(struct StringRef S) { return S.x+S.Ptr; } 123 124 // PR7567 125 typedef __attribute__ ((aligned(16))) struct f22s { unsigned long long x[2]; } L; 126 void f22(L x, L y) { } 127 // CHECK: @f22 128 // CHECK: %x = alloca{{.*}}, align 16 129 // CHECK: %y = alloca{{.*}}, align 16 130 131 132 133 // PR7714 134 struct f23S { 135 short f0; 136 unsigned f1; 137 int f2; 138 }; 139 140 141 void f23(int A, struct f23S B) { 142 // CHECK: define void @f23(i32 %A, i64 %B.coerce0, i32 %B.coerce1) 143 } 144 145 struct f24s { long a; int b; }; 146 147 struct f23S f24(struct f23S *X, struct f24s *P2) { 148 return *X; 149 150 // CHECK: define { i64, i32 } @f24(%struct.f23S* %X, %struct.f24s* %P2) 151 } 152 153 // rdar://8248065 154 typedef float v4f32 __attribute__((__vector_size__(16))); 155 v4f32 f25(v4f32 X) { 156 // CHECK: define <4 x float> @f25(<4 x float> %X) 157 // CHECK-NOT: alloca 158 // CHECK: alloca <4 x float> 159 // CHECK-NOT: alloca 160 // CHECK: store <4 x float> %X, <4 x float>* 161 // CHECK-NOT: store 162 // CHECK: ret <4 x float> 163 return X+X; 164 } 165 166 struct foo26 { 167 int *X; 168 float *Y; 169 }; 170 171 struct foo26 f26(struct foo26 *P) { 172 // CHECK: define { i32*, float* } @f26(%struct.foo26* %P) 173 return *P; 174 } 175 176 177 struct v4f32wrapper { 178 v4f32 v; 179 }; 180 181 struct v4f32wrapper f27(struct v4f32wrapper X) { 182 // CHECK: define <4 x float> @f27(<4 x float> %X.coerce) 183 return X; 184 } 185 186 // rdar://5711709 187 struct f28c { 188 double x; 189 int y; 190 }; 191 void f28(struct f28c C) { 192 // CHECK: define void @f28(double %C.coerce0, i32 %C.coerce1) 193 } 194 195 struct f29a { 196 struct c { 197 double x; 198 int y; 199 } x[1]; 200 }; 201 202 void f29a(struct f29a A) { 203 // CHECK: define void @f29a(double %A.coerce0, i32 %A.coerce1) 204 } 205 206 // rdar://8249586 207 struct S0 { char f0[8]; char f2; char f3; char f4; }; 208 void f30(struct S0 p_4) { 209 // CHECK: define void @f30(i64 %p_4.coerce0, i24 %p_4.coerce1) 210 } 211 212 // Pass the third element as a float when followed by tail padding. 213 // rdar://8251384 214 struct f31foo { float a, b, c; }; 215 float f31(struct f31foo X) { 216 // CHECK: define float @f31(<2 x float> %X.coerce0, float %X.coerce1) 217 return X.c; 218 } 219 220 _Complex float f32(_Complex float A, _Complex float B) { 221 // rdar://6379669 222 // CHECK: define <2 x float> @f32(<2 x float> %A.coerce, <2 x float> %B.coerce) 223 return A+B; 224 } 225 226 227 // rdar://8357396 228 struct f33s { long x; float c,d; }; 229 230 void f33(va_list X) { 231 va_arg(X, struct f33s); 232 } 233 234 typedef unsigned long long v1i64 __attribute__((__vector_size__(8))); 235 236 // rdar://8359248 237 // CHECK: define i64 @f34(i64 %arg.coerce) 238 v1i64 f34(v1i64 arg) { return arg; } 239 240 241 // rdar://8358475 242 // CHECK: define i64 @f35(i64 %arg.coerce) 243 typedef unsigned long v1i64_2 __attribute__((__vector_size__(8))); 244 v1i64_2 f35(v1i64_2 arg) { return arg+arg; } 245 246 // rdar://9122143 247 // CHECK: declare void @func(%struct._str* byval align 16) 248 typedef struct _str { 249 union { 250 long double a; 251 long c; 252 }; 253 } str; 254 255 void func(str s); 256 str ss; 257 void f9122143() 258 { 259 func(ss); 260 } 261 262 // CHECK: define double @f36(double %arg.coerce) 263 typedef unsigned v2i32 __attribute((__vector_size__(8))); 264 v2i32 f36(v2i32 arg) { return arg; } 265 266 // CHECK: declare void @f38(<8 x float>) 267 // CHECK: declare void @f37(<8 x float>) 268 typedef float __m256 __attribute__ ((__vector_size__ (32))); 269 typedef struct { 270 __m256 m; 271 } s256; 272 273 s256 x38; 274 __m256 x37; 275 276 void f38(s256 x); 277 void f37(__m256 x); 278 void f39() { f38(x38); f37(x37); } 279 280 // The two next tests make sure that the struct below is passed 281 // in the same way regardless of avx being used 282 283 // CHECK: declare void @func40(%struct.t128* byval align 16) 284 typedef float __m128 __attribute__ ((__vector_size__ (16))); 285 typedef struct t128 { 286 __m128 m; 287 __m128 n; 288 } two128; 289 290 extern void func40(two128 s); 291 void func41(two128 s) { 292 func40(s); 293 } 294 295 // CHECK: declare void @func42(%struct.t128_2* byval align 16) 296 typedef struct xxx { 297 __m128 array[2]; 298 } Atwo128; 299 typedef struct t128_2 { 300 Atwo128 x; 301 } SA; 302 303 extern void func42(SA s); 304 void func43(SA s) { 305 func42(s); 306 } 307