1 // RUN: %clang_cc1 -triple loongarch64 -target-feature +f -target-feature +d -target-abi lp64d -emit-llvm %s -o - | \
2 // RUN: FileCheck --check-prefix=CHECK-C %s
3 // RUN: %clang_cc1 -triple loongarch64 -target-feature +f -target-feature +d -target-abi lp64d -emit-llvm %s -o - -x c++ | \
4 // RUN: FileCheck --check-prefix=CHECK-CXX %s
6 // Fields containing empty structs are ignored when flattening
7 // structs to examine whether the structs can be passed via FARs, even in C++.
8 // But there is an exception that non-zero-length array of empty structures are
9 // not ignored in C++. These rules are not documented in psABI <https://www.github.com/loongson/la-abi-specs>
10 // but they match GCC behaviours.
14 struct empty
{ struct { struct { } e
; }; };
15 struct s1
{ struct empty e
; float f
; };
17 // CHECK-C: define{{.*}} float @test_s1(float {{.*}})
18 // CHECK-CXX: define{{.*}} float @_Z7test_s12s1(float {{.*}})
19 struct s1
test_s1(struct s1 a
) {
23 struct s2
{ struct empty e
; int32_t i
; float f
; };
25 // CHECK-C: define{{.*}} { i32, float } @test_s2(i32 {{.*}}, float {{.*}})
26 // CHECK-CXX: define{{.*}} { i32, float } @_Z7test_s22s2(i32 {{.*}}, float {{.*}})
27 struct s2
test_s2(struct s2 a
) {
31 struct s3
{ struct empty e
; float f
; float g
; };
33 // CHECK-C: define{{.*}} { float, float } @test_s3(float {{.*}}, float {{.*}})
34 // CHECK-CXX: define{{.*}} { float, float } @_Z7test_s32s3(float {{.*}}, float {{.*}})
35 struct s3
test_s3(struct s3 a
) {
39 struct s4
{ struct empty e
; float __complex__ c
; };
41 // CHECK-C: define{{.*}} { float, float } @test_s4(float {{.*}}, float {{.*}})
42 // CHECK-CXX: define{{.*}} { float, float } @_Z7test_s42s4(float {{.*}}, float {{.*}})
43 struct s4
test_s4(struct s4 a
) {
47 // An array of empty fields isn't ignored in C++ (this isn't explicit in the
48 // psABI, but matches observed g++ behaviour).
50 struct s5
{ struct empty e
[1]; float f
; };
52 // CHECK-C: define{{.*}} float @test_s5(float {{.*}})
53 // CHECK-CXX: define{{.*}} i64 @_Z7test_s52s5(i64 {{.*}})
54 struct s5
test_s5(struct s5 a
) {
58 struct empty_arr
{ struct { struct { } e
[1]; }; };
59 struct s6
{ struct empty_arr e
; float f
; };
61 // CHECK-C: define{{.*}} float @test_s6(float {{.*}})
62 // CHECK-CXX: define{{.*}} i64 @_Z7test_s62s6(i64 {{.*}})
63 struct s6
test_s6(struct s6 a
) {
67 struct s7
{ struct empty e
[0]; float f
; };
69 // CHECK-C: define{{.*}} float @test_s7(float {{.*}})
70 // CHECK-CXX: define{{.*}} float @_Z7test_s72s7(float {{.*}})
71 struct s7
test_s7(struct s7 a
) {
75 struct empty_arr0
{ struct { struct { } e
[0]; }; };
76 struct s8
{ struct empty_arr0 e
; float f
; };
78 // CHECK-C: define{{.*}} float @test_s8(float {{.*}})
79 // CHECK-CXX: define{{.*}} float @_Z7test_s82s8(float {{.*}})
80 struct s8
test_s8(struct s8 a
) {
84 /// Note: Below tests check how empty structs are passed while above tests check
85 /// empty structs as fields of container struct are ignored when flattening
86 /// structs to examine whether the container structs can be passed via FARs.
88 // CHECK-C: define{{.*}} void @test_s9()
89 // CHECK-CXX: define{{.*}} i64 @_Z7test_s92s9(i64 {{.*}})
90 struct s9
{ struct empty e
; };
91 struct s9
test_s9(struct s9 a
) {
95 // CHECK-C: define{{.*}} void @test_s10()
96 // CHECK-CXX: define{{.*}} i64 @_Z8test_s103s10(i64 {{.*}})
98 struct s10
test_s10(struct s10 a
) {
102 // CHECK-C: define{{.*}} void @test_s11()
103 // CHECK-CXX: define{{.*}} i64 @_Z8test_s113s11(i64 {{.*}})
104 struct s11
{ struct { } s
; };
105 struct s11
test_s11(struct s11 a
) {
109 // CHECK-C: define{{.*}} void @test_s12()
110 // CHECK-CXX: define{{.*}} void @_Z8test_s123s12()
111 struct s12
{ int i
[0]; };
112 struct s12
test_s12(struct s12 a
) {
116 // CHECK-C: define{{.*}} void @test_s13()
117 // CHECK-CXX: define{{.*}} void @_Z8test_s133s13()
118 struct s13
{ struct { } s
[0]; };
119 struct s13
test_s13(struct s13 a
) {
123 // CHECK-C: define{{.*}} void @test_s14()
124 // CHECK-CXX: define{{.*}} i64 @_Z8test_s143s14(i64 {{.*}})
125 struct s14
{ struct { } s
[1]; };
126 struct s14
test_s14(struct s14 a
) {
130 // CHECK-C: define{{.*}} void @test_s15()
131 // CHECK-CXX: define{{.*}} i64 @_Z8test_s153s15(i64 {{.*}})
132 struct s15
{ int : 0; };
133 struct s15
test_s15(struct s15 a
) {
137 // CHECK-C: define{{.*}} i64 @test_s16(i64 {{.*}})
138 // CHECK-CXX: define{{.*}} i64 @_Z8test_s163s16(i64 {{.*}})
139 struct s16
{ int : 1; };
140 struct s16
test_s16(struct s16 a
) {