1 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s -check-prefix=X64
2 ; RUN: llc < %s -mtriple=i686-unknown-linux-gnu | FileCheck %s -check-prefix=X32
6 ; Check the functionality of the local stack symbol table ordering
8 ; The test has a bunch of locals of various sizes that are referenced a
9 ; different number of times.
11 ; a : 120B, 9 uses, density = 0.075
12 ; aa : 4000B, 1 use, density = 0.00025
13 ; b : 4B, 1 use, density = 0.25
14 ; cc : 4000B, 2 uses density = 0.0005
15 ; d : 4B, 2 uses density = 0.5
16 ; e : 4B, 3 uses density = 0.75
17 ; f : 4B, 4 uses density = 1
19 ; Given the size, number of uses and calculated density (uses / size), we're
20 ; going to hope that f gets allocated closest to the stack pointer,
21 ; followed by e, d, b, then a (to check for just a few).
22 ; We use gnu-inline asm between calls to prevent registerization of addresses
23 ; so that we get exact counts.
25 ; The test is taken from something like this:
28 ; int f; // 4 uses. 4 / 4 = 1
29 ; int a[30]; // 9 uses. 8 / 120 = 0.06
30 ; int aa[1000]; // 1 use. 1 / 4000 =
31 ; int e; // 3 uses. 3 / 4 = 0.75
32 ; int cc[1000]; // 2 uses. 2 / 4000 =
33 ; int b; // 1 use. 1 / 4 = 0.25
34 ; int d; // 2 uses. 2 / 4 = 0.5
35 ; int aaa[1000]; // 2 uses. 2 / 4000
40 ; asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
43 ; asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
45 ; bar3(&aa, &aaa, &cc);
46 ; asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
49 ; asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
51 ; asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
54 ; asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
56 ; asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
60 ; asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
62 ; asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
66 ; X64: leaq 16(%rsp), %rdi
70 ; X64: movq %rsp, %rdi
75 ; X64: leaq 12(%rsp), %rdi
79 ; X64: leaq 4(%rsp), %rdi
83 ; X64: leaq 8(%rsp), %rdi
107 define void @foo() nounwind uwtable {
109 %f = alloca i32, align 4
110 %a = alloca [30 x i32], align 16
111 %aa = alloca [1000 x i32], align 16
112 %e = alloca i32, align 4
113 %cc = alloca [1000 x i32], align 16
114 %b = alloca i32, align 4
115 %d = alloca i32, align 4
116 %aaa = alloca [1000 x i32], align 16
117 call void @llvm.lifetime.start.p0(i64 4, ptr %f) #1
118 call void @llvm.lifetime.start.p0(i64 120, ptr %a) #1
119 call void @llvm.lifetime.start.p0(i64 4000, ptr %aa) #1
120 call void @llvm.lifetime.start.p0(i64 4, ptr %e) #1
121 call void @llvm.lifetime.start.p0(i64 4000, ptr %cc) #1
122 call void @llvm.lifetime.start.p0(i64 4, ptr %b) #1
123 call void @llvm.lifetime.start.p0(i64 4, ptr %d) #1
124 call void @llvm.lifetime.start.p0(i64 4000, ptr %aaa) #1
125 %call = call i32 (ptr, ...) @check_a(ptr %a)
126 %call1 = call i32 (ptr, ...) @bar1(ptr %aaa)
127 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1
128 %call2 = call i32 (ptr, ...) @bar1(ptr %a)
129 %call3 = call i32 (ptr, ...) @check_f(ptr %f)
130 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1
131 %call4 = call i32 (ptr, ...) @bar1(ptr %a)
132 %call5 = call i32 (ptr, ptr, ptr, ...) @bar3(ptr %aa, ptr %aaa, ptr %cc)
133 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1
134 %call6 = call i32 (ptr, ptr, ...) @bar2(ptr %a, ptr %cc)
135 %call7 = call i32 (ptr, ...) @check_b(ptr %b)
136 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1
137 %call8 = call i32 (ptr, ...) @bar1(ptr %a)
138 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1
139 %call9 = call i32 (ptr, ptr, ...) @bar2(ptr %a, ptr %f)
140 %call10 = call i32 (ptr, ...) @check_e(ptr %e)
141 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1
142 %call11 = call i32 (ptr, ...) @bar1(ptr %a)
143 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1
144 %call12 = call i32 (ptr, ptr, ...) @bar2(ptr %e, ptr %f)
145 %call13 = call i32 (ptr, ...) @check_d(ptr %d)
146 %call14 = call i32 (ptr, ...) @bar1(ptr %a)
147 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1
148 %call15 = call i32 (ptr, ptr, ptr, ...) @bar3(ptr %d, ptr %e, ptr %f)
149 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1
150 %call16 = call i32 (ptr, ...) @bar1(ptr %a)
151 call void @llvm.lifetime.end.p0(i64 4000, ptr %aaa) #1
152 call void @llvm.lifetime.end.p0(i64 4, ptr %d) #1
153 call void @llvm.lifetime.end.p0(i64 4, ptr %b) #1
154 call void @llvm.lifetime.end.p0(i64 4000, ptr %cc) #1
155 call void @llvm.lifetime.end.p0(i64 4, ptr %e) #1
156 call void @llvm.lifetime.end.p0(i64 4000, ptr %aa) #1
157 call void @llvm.lifetime.end.p0(i64 120, ptr %a) #1
158 call void @llvm.lifetime.end.p0(i64 4, ptr %f) #1
162 ; Function Attrs: nounwind
163 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #1
165 declare i32 @check_a(...) #2
166 declare i32 @bar1(...) #2
167 declare i32 @check_f(...) #2
168 declare i32 @bar3(...) #2
169 declare i32 @bar2(...) #2
170 declare i32 @check_b(...) #2
171 declare i32 @check_e(...) #2
172 declare i32 @check_d(...) #2
174 ; Function Attrs: nounwind
175 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #1