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