[ELF] Reorder SectionBase/InputSectionBase members
[llvm-project.git] / clang / test / Frontend / stack-layout-remark.c
blobb0ed03c80f24af0e55f8bf9de23e2d91955d1fdf
1 // Check that backend stack layout diagnostics are working correctly with and
2 // without debug information, and when optimizations are enabled
3 //
4 // REQUIRES: x86-registered-target
5 //
6 // RUN: rm -rf %t
7 // RUN: mkdir -p %t
8 // RUN: %clang_cc1 %s -emit-codegen-only -triple x86_64-unknown-linux-gnu -target-cpu corei7 -Rpass-analysis=stack-frame-layout -o /dev/null -O0 2>&1 | FileCheck %s --check-prefix=O0-NODEBUG
9 // RUN: %clang_cc1 %s -emit-codegen-only -triple x86_64-unknown-linux-gnu -target-cpu corei7 -Rpass-analysis=stack-frame-layout -o /dev/null -O0 -debug-info-kind=constructor -dwarf-version=5 -debugger-tuning=gdb 2>&1 | FileCheck %s --check-prefix=O0-DEBUG
10 // RUN: %clang_cc1 %s -emit-codegen-only -triple x86_64-unknown-linux-gnu -target-cpu corei7 -funwind-tables=2 -O3 -Rpass-analysis=stack-frame-layout -debug-info-kind=constructor -dwarf-version=5 -debugger-tuning=gdb -opt-record-file %t/stack-layout-remark.c.yml -opt-record-passes stack-frame-layout 2>&1 | FileCheck %s --check-prefix=O3-DEBUG
11 // RUN: cat %t/stack-layout-remark.c.yml | FileCheck %s --check-prefix=YAML
13 #define NULL (void*)0
15 extern void* allocate(unsigned size);
16 extern void deallocate(void* ptr);
17 extern int work(char *ary, int size);
18 extern int rand(void);
20 // Test YAML Ouput
21 // YAML: --- !Analysis
22 // YAML: Pass: stack-frame-layout
23 // YAML: Name: StackLayout
24 // YAML: DebugLoc: { File: '{{.*}}stack-layout-remark.c',{{[[:space:]]*}}Line: [[# @LINE + 24]],
25 // YAML: Function: foo
26 // YAML: Args:
27 // YAML: - Offset: '-40'
28 // YAML: - Type: Variable
29 // YAML: - Align: '16'
30 // YAML: - Size: '32'
31 // YAML: - DataLoc: 'a @ {{.*}}stack-layout-remark.c:[[# @LINE + 19]]'
32 // YAML: - DataLoc: 'f @ {{.*}}stack-layout-remark.c:[[# @LINE + 21]]'
34 // O0-NODEBUG: Function: foo
35 // O0-NODEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 16, Size: 32
36 // O0-NODEBUG-NEXT: Offset: [SP-72], Type: Variable, Align: 16, Size: 32
38 // O0-DEBUG: Function: foo
39 // O0-DEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 16, Size: 32
40 // O0-DEBUG-NEXT: a @ {{.*}}stack-layout-remark.c:[[# @LINE + 10]]
41 // O0-DEBUG-NEXT: Offset: [SP-72], Type: Variable, Align: 16, Size: 32
42 // O0-DEBUG-NEXT: f @ {{.*}}stack-layout-remark.c:[[# @LINE + 11]]
44 // O3-DEBUG: Function: foo
45 // O3-DEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 16, Size: 32
46 // O3-DEBUG-NEXT: a @ {{.*}}stack-layout-remark.c:[[# @LINE + 4]]
47 // O3-DEBUG-NEXT: f @ {{.*}}stack-layout-remark.c:[[# @LINE + 6]]
48 void foo() {
50 char a[32] = {0};
51 work(a, sizeof(a));
53 char f[32] = {0};
54 work(f, sizeof(f));
56 // O0-NODEBUG: Function: bar
57 // O0-NODEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 16, Size: 32
58 // O0-NODEBUG-NEXT: Offset: [SP-72], Type: Variable, Align: 16, Size: 32
60 // O0-DEBUG: Function: bar
61 // O0-DEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 16, Size: 32
62 // O0-DEBUG-NEXT: f @ {{.*}}stack-layout-remark.c:[[# @LINE + 10]]
63 // O0-DEBUG-NEXT: Offset: [SP-72], Type: Variable, Align: 16, Size: 32
64 // O0-DEBUG-NEXT: a @ {{.*}}stack-layout-remark.c:[[# @LINE + 10]]
66 // O3-DEBUG: Function: bar
67 // O3-DEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 16, Size: 32
68 // O3-DEBUG-NEXT: f @ {{.*}}stack-layout-remark.c:[[# @LINE + 4]]
69 // O3-DEBUG-NEXT: Offset: [SP-72], Type: Variable, Align: 16, Size: 32
70 // O3-DEBUG-NEXT: a @ {{.*}}stack-layout-remark.c:[[# @LINE + 4]]
71 void bar() {
72 char f[32] = {0};
74 char a[32] = {0};
75 work(a, sizeof(a));
77 work(f, sizeof(f));
80 struct Array {
81 int *data;
82 int size;
85 struct Result {
86 struct Array *data;
87 int sum;
90 // O0-NODEBUG: Function: cleanup_array
91 // O0-NODEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 8, Size: 8
93 // O0-DEBUG: Function: cleanup_array
94 // O0-DEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 8, Size: 8
95 // O0-DEBUG-NEXT: a @ {{.*}}stack-layout-remark.c:[[# @LINE + 5]]
97 // O3-DEBUG: Function: cleanup_array
98 // O3-DEBUG: Function: cleanup_result
99 // O3-DEBUG-NEXT: Offset: [SP-8], Type: Spill, Align: 16, Size: 8
100 void cleanup_array(struct Array *a) {
101 if (!a)
102 return;
103 if (!a->data)
104 return;
105 deallocate(a->data);
108 // O0-NODEBUG: Function: cleanup_result
109 // O0-NODEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 8, Size: 8
111 // O0-DEBUG: Function: cleanup_result
112 // O0-DEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 8, Size: 8
113 // O0-DEBUG-NEXT: res @ {{.*}}stack-layout-remark.c:[[# @LINE + 1]]
114 void cleanup_result(struct Result *res) {
115 if (!res)
116 return;
117 if (!res->data)
118 return;
119 cleanup_array(res->data);
120 deallocate(res->data);
123 extern void use_dot_vector(struct Array *data);
125 // O0-NODEBUG: Function: do_work
126 // O0-NODEBUG-NEXT: Offset: [SP-4], Type: Variable, Align: 4, Size: 4
127 // O0-NODEBUG-NEXT: Offset: [SP-16], Type: Variable, Align: 8, Size: 8
128 // O0-NODEBUG-NEXT: Offset: [SP-24], Type: Variable, Align: 8, Size: 8
129 // O0-NODEBUG-NEXT: Offset: [SP-32], Type: Variable, Align: 8, Size: 8
130 // O0-NODEBUG-NEXT: Offset: [SP-36], Type: Variable, Align: 4, Size: 4
131 // O0-NODEBUG-NEXT: Offset: [SP-48], Type: Variable, Align: 8, Size: 8
132 // O0-NODEBUG-NEXT: Offset: [SP-52], Type: Variable, Align: 4, Size: 4
133 // O0-NODEBUG-NEXT: Offset: [SP-56], Type: Variable, Align: 4, Size: 4
135 // O0-DEBUG: Function: do_work
136 // O0-DEBUG-NEXT: Offset: [SP-4], Type: Variable, Align: 4, Size: 4
137 // O0-DEBUG-NEXT: Offset: [SP-16], Type: Variable, Align: 8, Size: 8
138 // O0-DEBUG-NEXT: A @ {{.*}}stack-layout-remark.c:[[# @LINE + 20]]
139 // O0-DEBUG-NEXT: Offset: [SP-24], Type: Variable, Align: 8, Size: 8
140 // O0-DEBUG-NEXT: B @ {{.*}}stack-layout-remark.c:[[# @LINE + 18]]
141 // O0-DEBUG-NEXT: Offset: [SP-32], Type: Variable, Align: 8, Size: 8
142 // O0-DEBUG-NEXT: out @ {{.*}}stack-layout-remark.c:[[# @LINE + 16]]
143 // O0-DEBUG-NEXT: Offset: [SP-36], Type: Variable, Align: 4, Size: 4
144 // O0-DEBUG-NEXT: len @ {{.*}}stack-layout-remark.c:[[# @LINE + 19]]
145 // O0-DEBUG-NEXT: Offset: [SP-48], Type: Variable, Align: 8, Size: 8
146 // O0-DEBUG-NEXT: AB @ {{.*}}stack-layout-remark.c:[[# @LINE + 18]]
147 // O0-DEBUG-NEXT: Offset: [SP-52], Type: Variable, Align: 4, Size: 4
148 // O0-DEBUG-NEXT: sum @ {{.*}}stack-layout-remark.c:[[# @LINE + 32]]
149 // O0-DEBUG-NEXT: Offset: [SP-56], Type: Variable, Align: 4, Size: 4
150 // O0-DEBUG-NEXT: i @ {{.*}}stack-layout-remark.c:[[# @LINE + 31]]
152 // O3-DEBUG: Function: do_work
153 // O3-DEBUG-NEXT: Offset: [SP-8], Type: Spill, Align: 16, Size: 8
154 // O3-DEBUG-NEXT: Offset: [SP-16], Type: Spill, Align: 8, Size: 8
155 // O3-DEBUG-NEXT: Offset: [SP-24], Type: Spill, Align: 16, Size: 8
156 // O3-DEBUG-NEXT: Offset: [SP-32], Type: Spill, Align: 8, Size: 8
157 // O3-DEBUG-NEXT: Offset: [SP-40], Type: Spill, Align: 16, Size: 8
158 int do_work(struct Array *A, struct Array *B, struct Result *out) {
159 if (!A || !B)
160 return -1;
161 if (A->size != B->size)
162 return -1;
163 const int len = A->size;
164 struct Array *AB;
165 if (out->data == NULL) {
166 AB = (struct Array *)allocate(sizeof(struct Array));
167 AB->data = NULL;
168 AB->size = 0;
169 out->data = AB;
170 } else {
171 AB = out->data;
174 if (AB->data)
175 deallocate(AB->data);
177 AB->data = (int *)allocate(len * sizeof(int));
178 AB->size = len;
180 int sum = 0;
181 for (int i = 0; i < len; ++i) {
182 AB->data[i] = A->data[i] * B->data[i];
183 sum += AB->data[i];
185 return sum;
188 // O0-NODEBUG: Function: gen_array
189 // O0-NODEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 8, Size: 8
190 // O0-NODEBUG-NEXT: Offset: [SP-12], Type: Variable, Align: 4, Size: 4
191 // O0-NODEBUG-NEXT: Offset: [SP-24], Type: Variable, Align: 8, Size: 8
192 // O0-NODEBUG-NEXT: Offset: [SP-28], Type: Variable, Align: 4, Size: 4
194 // O0-DEBUG: Function: gen_array
195 // O0-DEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 8, Size: 8
196 // O0-DEBUG-NEXT: Offset: [SP-12], Type: Variable, Align: 4, Size: 4
197 // O0-DEBUG-NEXT: size @ {{.*}}stack-layout-remark.c:[[# @LINE + 10]]
198 // O0-DEBUG-NEXT: Offset: [SP-24], Type: Variable, Align: 8, Size: 8
199 // O0-DEBUG-NEXT: res @ {{.*}}stack-layout-remark.c:[[# @LINE + 11]]
200 // O0-DEBUG-NEXT: Offset: [SP-28], Type: Variable, Align: 4, Size: 4
201 // O0-DEBUG-NEXT: i @ {{.*}}stack-layout-remark.c:[[# @LINE + 13]]
203 // O3-DEBUG: Function: gen_array
204 // O3-DEBUG-NEXT: Offset: [SP-8], Type: Spill, Align: 16, Size: 8
205 // O3-DEBUG-NEXT: Offset: [SP-16], Type: Spill, Align: 8, Size: 8
206 // O3-DEBUG-NEXT: Offset: [SP-24], Type: Spill, Align: 16, Size: 8
207 struct Array *gen_array(int size) {
208 if (size < 0)
209 return NULL;
210 struct Array *res = (struct Array *)allocate(sizeof(struct Array));
211 res->size = size;
212 res->data = (int *)allocate(size * sizeof(int));
214 for (int i = 0; i < size; ++i) {
215 res->data[i] = rand();
218 return res;
221 // YAML: --- !Analysis
222 // YAML: Pass: stack-frame-layout
223 // YAML: Name: StackLayout
224 // YAML: DebugLoc: { File: '{{.*}}stack-layout-remark.c',{{[[:space:]]*}}Line: [[# @LINE + 59]],
225 // YAML: Function: caller
226 // YAML: Args:
227 // YAML: - Offset: '-8'
228 // YAML: - Type: Spill
229 // YAML: - Align: '16'
230 // YAML: - Size: '8'
231 // YAML: - Offset: '-16'
232 // YAML: - Type: Spill
233 // YAML: - Align: '8'
234 // YAML: - Size: '8'
235 // YAML: - Offset: '-24'
236 // YAML: - Type: Spill
237 // YAML: - Align: '16'
238 // YAML: - Size: '8'
239 // YAML: - Offset: '-32'
240 // YAML: - Type: Spill
241 // YAML: - Align: '8'
242 // YAML: - Size: '8'
243 // YAML: - Offset: '-40'
244 // YAML: - Type: Spill
245 // YAML: - Align: '16'
246 // YAML: - Size: '8'
247 // YAML: - Offset: '-48'
248 // YAML: - Type: Spill
249 // YAML: - Align: '8'
250 // YAML: - Size: '8'
252 // O0-NODEBUG: Function: caller
253 // O0-NODEBUG-NEXT: Offset: [SP-4], Type: Variable, Align: 4, Size: 4
254 // O0-NODEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 4, Size: 4
255 // O0-NODEBUG-NEXT: Offset: [SP-16], Type: Variable, Align: 8, Size: 8
256 // O0-NODEBUG-NEXT: Offset: [SP-24], Type: Variable, Align: 8, Size: 8
257 // O0-NODEBUG-NEXT: Offset: [SP-32], Type: Variable, Align: 8, Size: 8
258 // O0-NODEBUG-NEXT: Offset: [SP-36], Type: Variable, Align: 4, Size: 4
259 // O0-NODEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 4, Size: 4
261 // O0-DEBUG: Function: caller
262 // O0-DEBUG-NEXT: Offset: [SP-4], Type: Variable, Align: 4, Size: 4
263 // O0-DEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 4, Size: 4
264 // O0-DEBUG-NEXT: size @ {{.*}}stack-layout-remark.c:[[# @LINE + 20]]
265 // O0-DEBUG-NEXT: Offset: [SP-16], Type: Variable, Align: 8, Size: 8
266 // O0-DEBUG-NEXT: A @ {{.*}}stack-layout-remark.c:[[# @LINE + 19]]
267 // O0-DEBUG-NEXT: Offset: [SP-24], Type: Variable, Align: 8, Size: 8
268 // O0-DEBUG-NEXT: B @ {{.*}}stack-layout-remark.c:[[# @LINE + 18]]
269 // O0-DEBUG-NEXT: Offset: [SP-32], Type: Variable, Align: 8, Size: 8
270 // O0-DEBUG-NEXT: res @ {{.*}}stack-layout-remark.c:[[# @LINE + 17]]
271 // O0-DEBUG-NEXT: Offset: [SP-36], Type: Variable, Align: 4, Size: 4
272 // O0-DEBUG-NEXT: ret @ {{.*}}stack-layout-remark.c:[[# @LINE + 16]]
273 // O0-DEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 4, Size: 4
274 // O0-DEBUG-NEXT: err @ {{.*}}stack-layout-remark.c:[[# @LINE + 16]]
276 // O3-DEBUG: Function: caller
277 // O3-DEBUG-NEXT: Offset: [SP-8], Type: Spill, Align: 16, Size: 8
278 // O3-DEBUG-NEXT: Offset: [SP-16], Type: Spill, Align: 8, Size: 8
279 // O3-DEBUG-NEXT: Offset: [SP-24], Type: Spill, Align: 16, Size: 8
280 // O3-DEBUG-NEXT: Offset: [SP-32], Type: Spill, Align: 8, Size: 8
281 // O3-DEBUG-NEXT: Offset: [SP-40], Type: Spill, Align: 16, Size: 8
282 // O3-DEBUG-NEXT: Offset: [SP-48], Type: Spill, Align: 8, Size: 8
283 int caller() {
284 const int size = 100;
285 struct Array *A = gen_array(size);
286 struct Array *B = gen_array(size);
287 struct Result *res = (struct Result *)allocate(sizeof(struct Result));
288 int ret = -1;
290 int err = do_work(A, B, res);
291 if (err == -1) {
292 goto cleanup;
295 ret = res->sum;
296 if (ret == -1)
297 return caller();
299 use_dot_vector(res->data);
301 cleanup:
302 cleanup_array(A);
303 cleanup_array(B);
304 cleanup_result(res);
306 return ret;