Home | History | Annotate | Download | only in X86
      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