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 3 4 ; CHECK-LABEL: foo 5 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. 10 ; 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 18 ; 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. 24 ; 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 36 ; 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 ; } 65 ; 66 ; X64: leaq 16(%rsp), %rdi 67 ; X64: callq check_a 68 ; X64: callq bar1 69 ; X64: callq bar1 70 ; X64: leaq (%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 85 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 105 106 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 %0 = bitcast i32* %f to i8* 118 call void @llvm.lifetime.start(i64 4, i8* %0) #1 119 %1 = bitcast [30 x i32]* %a to i8* 120 call void @llvm.lifetime.start(i64 120, i8* %1) #1 121 %2 = bitcast [1000 x i32]* %aa to i8* 122 call void @llvm.lifetime.start(i64 4000, i8* %2) #1 123 %3 = bitcast i32* %e to i8* 124 call void @llvm.lifetime.start(i64 4, i8* %3) #1 125 %4 = bitcast [1000 x i32]* %cc to i8* 126 call void @llvm.lifetime.start(i64 4000, i8* %4) #1 127 %5 = bitcast i32* %b to i8* 128 call void @llvm.lifetime.start(i64 4, i8* %5) #1 129 %6 = bitcast i32* %d to i8* 130 call void @llvm.lifetime.start(i64 4, i8* %6) #1 131 %7 = bitcast [1000 x i32]* %aaa to i8* 132 call void @llvm.lifetime.start(i64 4000, i8* %7) #1 133 %call = call i32 ([30 x i32]*, ...) bitcast (i32 (...)* @check_a to i32 ([30 x i32]*, ...)*)([30 x i32]* %a) 134 %call1 = call i32 ([1000 x i32]*, ...) bitcast (i32 (...)* @bar1 to i32 ([1000 x i32]*, ...)*)([1000 x i32]* %aaa) 135 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1 136 %call2 = call i32 ([30 x i32]*, ...) bitcast (i32 (...)* @bar1 to i32 ([30 x i32]*, ...)*)([30 x i32]* %a) 137 %call3 = call i32 (i32*, ...) bitcast (i32 (...)* @check_f to i32 (i32*, ...)*)(i32* %f) 138 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1 139 %call4 = call i32 ([30 x i32]*, ...) bitcast (i32 (...)* @bar1 to i32 ([30 x i32]*, ...)*)([30 x i32]* %a) 140 %call5 = call i32 ([1000 x i32]*, [1000 x i32]*, [1000 x i32]*, ...) bitcast (i32 (...)* @bar3 to i32 ([1000 x i32]*, [1000 x i32]*, [1000 x i32]*, ...)*)([1000 x i32]* %aa, [1000 x i32]* %aaa, [1000 x i32]* %cc) 141 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1 142 %call6 = call i32 ([30 x i32]*, [1000 x i32]*, ...) bitcast (i32 (...)* @bar2 to i32 ([30 x i32]*, [1000 x i32]*, ...)*)([30 x i32]* %a, [1000 x i32]* %cc) 143 %call7 = call i32 (i32*, ...) bitcast (i32 (...)* @check_b to i32 (i32*, ...)*)(i32* %b) 144 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1 145 %call8 = call i32 ([30 x i32]*, ...) bitcast (i32 (...)* @bar1 to i32 ([30 x i32]*, ...)*)([30 x i32]* %a) 146 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1 147 %call9 = call i32 ([30 x i32]*, i32*, ...) bitcast (i32 (...)* @bar2 to i32 ([30 x i32]*, i32*, ...)*)([30 x i32]* %a, i32* %f) 148 %call10 = call i32 (i32*, ...) bitcast (i32 (...)* @check_e to i32 (i32*, ...)*)(i32* %e) 149 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1 150 %call11 = call i32 ([30 x i32]*, ...) bitcast (i32 (...)* @bar1 to i32 ([30 x i32]*, ...)*)([30 x i32]* %a) 151 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1 152 %call12 = call i32 (i32*, i32*, ...) bitcast (i32 (...)* @bar2 to i32 (i32*, i32*, ...)*)(i32* %e, i32* %f) 153 %call13 = call i32 (i32*, ...) bitcast (i32 (...)* @check_d to i32 (i32*, ...)*)(i32* %d) 154 %call14 = call i32 ([30 x i32]*, ...) bitcast (i32 (...)* @bar1 to i32 ([30 x i32]*, ...)*)([30 x i32]* %a) 155 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1 156 %call15 = call i32 (i32*, i32*, i32*, ...) bitcast (i32 (...)* @bar3 to i32 (i32*, i32*, i32*, ...)*)(i32* %d, i32* %e, i32* %f) 157 call void asm sideeffect "", "~{esi},~{edi},~{ebp},~{ebx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{rbp},~{dirflag},~{fpsr},~{flags}"() #1 158 %call16 = call i32 ([30 x i32]*, ...) bitcast (i32 (...)* @bar1 to i32 ([30 x i32]*, ...)*)([30 x i32]* %a) 159 call void @llvm.lifetime.end(i64 4000, i8* %7) #1 160 call void @llvm.lifetime.end(i64 4, i8* %6) #1 161 call void @llvm.lifetime.end(i64 4, i8* %5) #1 162 call void @llvm.lifetime.end(i64 4000, i8* %4) #1 163 call void @llvm.lifetime.end(i64 4, i8* %3) #1 164 call void @llvm.lifetime.end(i64 4000, i8* %2) #1 165 call void @llvm.lifetime.end(i64 120, i8* %1) #1 166 call void @llvm.lifetime.end(i64 4, i8* %0) #1 167 ret void 168 } 169 170 ; Function Attrs: nounwind 171 declare void @llvm.lifetime.start(i64, i8* nocapture) #1 172 173 declare i32 @check_a(...) #2 174 declare i32 @bar1(...) #2 175 declare i32 @check_f(...) #2 176 declare i32 @bar3(...) #2 177 declare i32 @bar2(...) #2 178 declare i32 @check_b(...) #2 179 declare i32 @check_e(...) #2 180 declare i32 @check_d(...) #2 181 182 ; Function Attrs: nounwind 183 declare void @llvm.lifetime.end(i64, i8* nocapture) #1 184 185