1- // RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s
2- // RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s --check-prefix =CHECK-GNU- C
3- // RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix =CHECK-GNU- CXX
1+ // RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,DARWIN
2+ // RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s --check-prefixes =CHECK, C
3+ // RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefixes =CHECK, CXX
44
55// Empty structs are ignored for PCS purposes on Darwin and in C mode elsewhere.
66// In C++ mode on ELF they consume a register slot though. Functions are
1515
1616struct Empty {};
1717
18- // CHECK : define{{.*}} i32 @empty_arg(i32 noundef %a)
19- // CHECK-GNU- C: define{{.*}} i32 @empty_arg(i32 noundef %a)
20- // CHECK-GNU- CXX: define{{.*}} i32 @empty_arg(i8 %e.coerce, i32 noundef %a)
18+ // DARWIN : define{{.*}} i32 @empty_arg(i32 noundef %a)
19+ // C: define{{.*}} i32 @empty_arg(i32 noundef %a)
20+ // CXX: define{{.*}} i32 @empty_arg(i8 %e.coerce, i32 noundef %a)
2121EXTERNC int empty_arg (struct Empty e, int a) {
2222 return a;
2323}
2424
25- // CHECK : define{{.*}} void @empty_ret()
26- // CHECK-GNU- C: define{{.*}} void @empty_ret()
27- // CHECK-GNU- CXX: define{{.*}} void @empty_ret()
25+ // DARWIN : define{{.*}} void @empty_ret()
26+ // C: define{{.*}} void @empty_ret()
27+ // CXX: define{{.*}} void @empty_ret()
2828EXTERNC struct Empty empty_ret (void ) {
2929 struct Empty e;
3030 return e;
@@ -38,30 +38,75 @@ struct SuperEmpty {
3838 int arr[0 ];
3939};
4040
41- // CHECK : define{{.*}} i32 @super_empty_arg(i32 noundef %a)
42- // CHECK-GNU- C: define{{.*}} i32 @super_empty_arg(i32 noundef %a)
43- // CHECK-GNU- CXX: define{{.*}} i32 @super_empty_arg(i32 noundef %a)
41+ // DARWIN : define{{.*}} i32 @super_empty_arg(i32 noundef %a)
42+ // C: define{{.*}} i32 @super_empty_arg(i32 noundef %a)
43+ // CXX: define{{.*}} i32 @super_empty_arg(i32 noundef %a)
4444EXTERNC int super_empty_arg (struct SuperEmpty e, int a) {
4545 return a;
4646}
4747
48- // This is not empty. It has 0 size but consumes a register slot for GCC.
48+ // This is also not empty, and non-standard. We previously considered it to
49+ // consume a register slot, but GCC does not, so we match that.
4950
5051struct SortOfEmpty {
5152 struct SuperEmpty e;
5253};
5354
54- // CHECK : define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
55- // CHECK-GNU- C: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
56- // CHECK-GNU- CXX: define{{.*}} i32 @sort_of_empty_arg(i8 %e.coerce, i32 noundef %a)
57- EXTERNC int sort_of_empty_arg (struct Empty e, int a) {
55+ // DARWIN : define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
56+ // C: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
57+ // CXX: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
58+ EXTERNC int sort_of_empty_arg (struct SortOfEmpty e, int a) {
5859 return a;
5960}
6061
61- // CHECK : define{{.*}} void @sort_of_empty_ret()
62- // CHECK-GNU- C: define{{.*}} void @sort_of_empty_ret()
63- // CHECK-GNU- CXX: define{{.*}} void @sort_of_empty_ret()
62+ // DARWIN : define{{.*}} void @sort_of_empty_ret()
63+ // C: define{{.*}} void @sort_of_empty_ret()
64+ // CXX: define{{.*}} void @sort_of_empty_ret()
6465EXTERNC struct SortOfEmpty sort_of_empty_ret (void ) {
6566 struct SortOfEmpty e;
6667 return e;
6768}
69+
70+ #include < stdarg.h>
71+
72+ // va_arg matches the above rules, consuming an incoming argument in cases
73+ // where one would be passed, and not doing so when the argument should be
74+ // ignored.
75+
76+ EXTERNC struct Empty empty_arg_variadic (int a, ...) {
77+ // CHECK-LABEL: @empty_arg_variadic(
78+ // DARWIN-NOT: {{ getelementptr }}
79+ // C-NOT: {{ getelementptr }}
80+ // CXX: %new_reg_offs = add i32 %gr_offs, 8
81+ // CXX: %new_stack = getelementptr inbounds i8, ptr %stack, i64 8
82+ va_list vl;
83+ va_start (vl, a);
84+ struct Empty b = va_arg (vl, struct Empty );
85+ va_end (vl);
86+ return b;
87+ }
88+
89+ EXTERNC struct SuperEmpty super_empty_arg_variadic (int a, ...) {
90+ // CHECK-LABEL: @super_empty_arg_variadic(
91+ // DARWIN-NOT: {{ getelementptr }}
92+ // C-NOT: {{ getelementptr }}
93+ // CXX-NOT: {{ getelementptr }}
94+ va_list vl;
95+ va_start (vl, a);
96+ struct SuperEmpty b = va_arg (vl, struct SuperEmpty );
97+ va_end (vl);
98+ return b;
99+ }
100+
101+ EXTERNC struct SortOfEmpty sort_of_empty_arg_variadic (int a, ...) {
102+ // CHECK-LABEL: @sort_of_empty_arg_variadic(
103+ // DARWIN: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i64 0
104+ // C-NOT: {{ getelementptr }}
105+ // CXX-NOT: {{ getelementptr }}
106+ va_list vl;
107+ va_start (vl, a);
108+ struct SortOfEmpty b = va_arg (vl, struct SortOfEmpty );
109+ va_end (vl);
110+ return b;
111+ }
112+
0 commit comments