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