Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / X86 / local_stack_symbol_ordering.ll
blobf95153bf29108d896b1f8027abc9424348d3f325
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
4 ; CHECK-LABEL: foo
6 ; Check the functionality of the local stack symbol table ordering
7 ; heuristics.
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:
26 ; void foo()
27 ; {
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
37
38 ;   check_a(&a);
39 ;   bar1(&aaa);
40 ;   asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
41 ;   bar1(&a);
42 ;   check_f(&f);
43 ;   asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
44 ;   bar1(&a);
45 ;   bar3(&aa, &aaa, &cc);
46 ;   asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
47 ;   bar2(&a,&cc);
48 ;   check_b(&b);
49 ;   asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
50 ;   bar1(&a);
51 ;   asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
52 ;   bar2(&a, &f);
53 ;   check_e(&e);
54 ;   asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
55 ;   bar1(&a);
56 ;   asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
57 ;   bar2(&e, &f);
58 ;   check_d(&d);
59 ;   bar1(&a);
60 ;   asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
61 ;   bar3(&d, &e, &f);
62 ;   asm ("":::"esi","edi","ebp","ebx","rbx","r12","r13","r14","r15","rbp");
63 ;   bar1(&a);
64 ; }
66 ; X64: leaq 16(%rsp), %rdi
67 ; X64: callq check_a
68 ; X64: callq bar1
69 ; X64: callq bar1
70 ; X64: movq %rsp, %rdi
71 ; X64: callq check_f
72 ; X64: callq bar1
73 ; X64: callq bar3
74 ; X64: callq bar2
75 ; X64: leaq 12(%rsp), %rdi
76 ; X64: callq check_b
77 ; X64: callq bar1
78 ; X64: callq bar2
79 ; X64: leaq 4(%rsp), %rdi
80 ; X64: callq check_e
81 ; X64: callq bar1
82 ; X64: callq bar2
83 ; X64: leaq 8(%rsp), %rdi
84 ; X64: callq check_d
86 ; X32: leal 32(%esp)
87 ; X32: calll check_a
88 ; X32: calll bar1
89 ; X32: calll bar1
90 ; X32: leal 16(%esp)
91 ; X32: calll check_f
92 ; X32: calll bar1
93 ; X32: calll bar3
94 ; X32: calll bar2
95 ; X32: leal 28(%esp)
96 ; X32: calll check_b
97 ; X32: calll bar1
98 ; X32: calll bar2
99 ; X32: leal 20(%esp)
100 ; X32: calll check_e
101 ; X32: calll bar1
102 ; X32: calll bar2
103 ; X32: leal 24(%esp)
104 ; X32: calll check_d
107 define void @foo() nounwind uwtable {
108 entry:
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
159   ret void
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