1 // REQUIRES: arm-registered-target
2 // RUN: %clang_cc1 -triple arm-none-none-eabi \
3 // RUN:   -O2 \
4 // RUN:   -target-cpu cortex-a8 \
5 // RUN:   -emit-llvm -o - %s | FileCheck %s
6 
7 extern "C" {
8 
9 // Base case, nothing interesting.
10 struct S {
11   int x, y;
12 };
13 
14 void f0(int, S);
15 void f0m(int, int, int, int, int, S);
g0()16 void g0() {
17   S s = {6, 7};
18   f0(1, s);
19   f0m(1, 2, 3, 4, 5, s);
20 }
21 // CHECK: define{{.*}} void @g0
22 // CHECK: call void @f0(i32 1, [2 x i32] [i32 6, i32 7]
23 // CHECK: call void @f0m(i32 1, i32 2, i32 3, i32 4, i32 5, [2 x i32] [i32 6, i32 7]
24 // CHECK: declare void @f0(i32, [2 x i32])
25 // CHECK: declare void @f0m(i32, i32, i32, i32, i32, [2 x i32])
26 
27 // Aligned struct, passed according to its natural alignment.
28 struct __attribute__((aligned(8))) S8 {
29   int x, y;
30 } s8;
31 
32 void f1(int, S8);
33 void f1m(int, int, int, int, int, S8);
g1()34 void g1() {
35   S8 s = {6, 7};
36   f1(1, s);
37   f1m(1, 2, 3, 4, 5, s);
38 }
39 // CHECK: define{{.*}} void @g1
40 // CHECK: call void @f1(i32 1, [2 x i32] [i32 6, i32 7]
41 // CHECK: call void @f1m(i32 1, i32 2, i32 3, i32 4, i32 5, [2 x i32] [i32 6, i32 7]
42 // CHECK: declare void @f1(i32, [2 x i32])
43 // CHECK: declare void @f1m(i32, i32, i32, i32, i32, [2 x i32])
44 
45 // Aligned struct, passed according to its natural alignment.
46 struct alignas(16) S16 {
47   int x, y;
48 };
49 
50 extern "C" void f2(int, S16);
51 extern "C" void f2m(int, int, int, int, int, S16);
52 
g2()53 void g2() {
54   S16 s = {6, 7};
55   f2(1, s);
56   f2m(1, 2, 3, 4, 5, s);
57 }
58 // CHECK: define{{.*}} void @g2
59 // CHECK: call void @f2(i32 1, [4 x i32] [i32 6, i32 7
60 // CHECK: call void @f2m(i32 1, i32 2, i32 3, i32 4, i32 5, [4 x i32] [i32 6, i32 7
61 // CHECK: declare void @f2(i32, [4 x i32])
62 // CHECK: declare void @f2m(i32, i32, i32, i32, i32, [4 x i32])
63 
64 // Increased natural alignment.
65 struct SF8 {
66   int x __attribute__((aligned(8)));
67   int y;
68 };
69 
70 void f3(int, SF8);
71 void f3m(int, int, int, int, int, SF8);
g3()72 void g3() {
73   SF8 s = {6, 7};
74   f3(1, s);
75   f3m(1, 2, 3, 4, 5, s);
76 }
77 // CHECK: define{{.*}} void @g3
78 // CHECK: call void @f3(i32 1, [1 x i64] [i64 30064771078]
79 // CHECK: call void @f3m(i32 1, i32 2, i32 3, i32 4, i32 5, [1 x i64] [i64 30064771078]
80 // CHECK: declare void @f3(i32, [1 x i64])
81 // CHECK: declare void @f3m(i32, i32, i32, i32, i32, [1 x i64])
82 
83 // Increased natural alignment, capped to 8 though.
84 struct SF16 {
85   int x;
86   int y alignas(16);
87   int z, a, b, c, d, e, f, g, h, i, j, k;
88 };
89 
90 void f4(int, SF16);
91 void f4m(int, int, int, int, int, SF16);
g4()92 void g4() {
93   SF16 s = {6, 7};
94   f4(1, s);
95   f4m(1, 2, 3, 4, 5, s);
96 }
97 // CHECK: define{{.*}} void @g4
98 // CHECK: call void @f4(i32 1, %struct.SF16* nonnull byval(%struct.SF16) align 8
99 // CHECK: call void @f4m(i32 1, i32 2, i32 3, i32 4, i32 5, %struct.SF16* nonnull byval(%struct.SF16) align 8
100 // CHECK: declare void @f4(i32, %struct.SF16* byval(%struct.SF16) align 8)
101 // CHECK: declare void @f4m(i32, i32, i32, i32, i32, %struct.SF16* byval(%struct.SF16) align 8)
102 
103 // Packed structure.
104 struct  __attribute__((packed)) P {
105   int x;
106   long long u;
107 };
108 
109 void f5(int, P);
110 void f5m(int, int, int, int, int, P);
g5()111 void g5() {
112   P s = {6, 7};
113   f5(1, s);
114   f5m(1, 2, 3, 4, 5, s);
115 }
116 // CHECK: define{{.*}} void @g5
117 // CHECK: call void @f5(i32 1, [3 x i32] [i32 6, i32 7, i32 0])
118 // CHECK: call void @f5m(i32 1, i32 2, i32 3, i32 4, i32 5, [3 x i32] [i32 6, i32 7, i32 0])
119 // CHECK: declare void @f5(i32, [3 x i32])
120 // CHECK: declare void @f5m(i32, i32, i32, i32, i32, [3 x i32])
121 
122 
123 // Packed and aligned, alignement causes padding at the end.
124 struct  __attribute__((packed, aligned(8))) P8 {
125   int x;
126   long long u;
127 };
128 
129 void f6(int, P8);
130 void f6m(int, int, int, int, int, P8);
g6()131 void g6() {
132   P8 s = {6, 7};
133   f6(1, s);
134   f6m(1, 2, 3, 4, 5, s);
135 }
136 // CHECK: define{{.*}} void @g6
137 // CHECK: call void @f6(i32 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0])
138 // CHECK: call void @f6m(i32 1, i32 2, i32 3, i32 4, i32 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0])
139 // CHECK: declare void @f6(i32, [4 x i32])
140 // CHECK: declare void @f6m(i32, i32, i32, i32, i32, [4 x i32])
141 }
142