Home | History | Annotate | Download | only in X86
      1 ; We specify -mcpu explicitly to avoid instruction reordering that happens on
      2 ; some setups (e.g., Atom) from affecting the output.
      3 ; RUN: llc < %s -mcpu=core2 -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN32
      4 ; RUN: llc < %s -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X86
      5 ; RUN: llc < %s -mtriple=i386-pc-linux | FileCheck %s -check-prefix=LINUX
      6 ; RUN: llc < %s -mcpu=core2 -O0 -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN32
      7 ; RUN: llc < %s -O0 -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X86
      8 ; RUN: llc < %s -O0 -mtriple=i386-pc-linux | FileCheck %s -check-prefix=LINUX
      9 
     10 ; The SysV ABI used by most Unixes and Mingw on x86 specifies that an sret pointer
     11 ; is callee-cleanup. However, in MSVC's cdecl calling convention, sret pointer
     12 ; arguments are caller-cleanup like normal arguments.
     13 
     14 define void @sret1(i8* sret %x) nounwind {
     15 entry:
     16 ; WIN32:      sret1
     17 ; WIN32:      movb $42, (%eax)
     18 ; WIN32-NOT:  popl %eax
     19 ; WIN32:    {{ret$}}
     20 
     21 ; MINGW_X86:  sret1
     22 ; MINGW_X86:  ret $4
     23 
     24 ; LINUX:      sret1
     25 ; LINUX:      ret $4
     26 
     27   store i8 42, i8* %x, align 4
     28   ret void
     29 }
     30 
     31 define void @sret2(i8* sret %x, i8 %y) nounwind {
     32 entry:
     33 ; WIN32:      sret2
     34 ; WIN32:      movb {{.*}}, (%eax)
     35 ; WIN32-NOT:  popl %eax
     36 ; WIN32:    {{ret$}}
     37 
     38 ; MINGW_X86:  sret2
     39 ; MINGW_X86:  ret $4
     40 
     41 ; LINUX:      sret2
     42 ; LINUX:      ret $4
     43 
     44   store i8 %y, i8* %x
     45   ret void
     46 }
     47 
     48 define void @sret3(i8* sret %x, i8* %y) nounwind {
     49 entry:
     50 ; WIN32:      sret3
     51 ; WIN32:      movb $42, (%eax)
     52 ; WIN32-NOT:  movb $13, (%eax)
     53 ; WIN32-NOT:  popl %eax
     54 ; WIN32:    {{ret$}}
     55 
     56 ; MINGW_X86:  sret3
     57 ; MINGW_X86:  ret $4
     58 
     59 ; LINUX:      sret3
     60 ; LINUX:      ret $4
     61 
     62   store i8 42, i8* %x
     63   store i8 13, i8* %y
     64   ret void
     65 }
     66 
     67 ; PR15556
     68 %struct.S4 = type { i32, i32, i32 }
     69 
     70 define void @sret4(%struct.S4* noalias sret %agg.result) {
     71 entry:
     72 ; WIN32:     sret4
     73 ; WIN32:     movl $42, (%eax)
     74 ; WIN32-NOT: popl %eax
     75 ; WIN32:   {{ret$}}
     76 
     77 ; MINGW_X86: sret4
     78 ; MINGW_X86: ret $4
     79 
     80 ; LINUX:     sret4
     81 ; LINUX:     ret $4
     82 
     83   %x = getelementptr inbounds %struct.S4* %agg.result, i32 0, i32 0
     84   store i32 42, i32* %x, align 4
     85   ret void
     86 }
     87 
     88 %struct.S5 = type { i32 }
     89 %class.C5 = type { i8 }
     90 
     91 define x86_thiscallcc void @"\01?foo@C5@@QAE?AUS5@@XZ"(%struct.S5* noalias sret %agg.result, %class.C5* %this) {
     92 entry:
     93   %this.addr = alloca %class.C5*, align 4
     94   store %class.C5* %this, %class.C5** %this.addr, align 4
     95   %this1 = load %class.C5** %this.addr
     96   %x = getelementptr inbounds %struct.S5* %agg.result, i32 0, i32 0
     97   store i32 42, i32* %x, align 4
     98   ret void
     99 ; WIN32:     {{^}}"?foo@C5@@QAE?AUS5@@XZ":
    100 
    101 ; The address of the return structure is passed as an implicit parameter.
    102 ; In the -O0 build, %eax is spilled at the beginning of the function, hence we
    103 ; should match both 4(%esp) and 8(%esp).
    104 ; WIN32:     {{[48]}}(%esp), %eax
    105 ; WIN32:     movl $42, (%eax)
    106 ; WIN32:     ret $4
    107 }
    108 
    109 define void @call_foo5() {
    110 entry:
    111   %c = alloca %class.C5, align 1
    112   %s = alloca %struct.S5, align 4
    113   call x86_thiscallcc void @"\01?foo@C5@@QAE?AUS5@@XZ"(%struct.S5* sret %s, %class.C5* %c)
    114 ; WIN32:      {{^}}_call_foo5:
    115 
    116 ; Load the address of the result and put it onto stack
    117 ; (through %ecx in the -O0 build).
    118 ; WIN32:      leal {{[0-9]+}}(%esp), %e{{[a-d]}}x
    119 ; WIN32:      movl %e{{[a-d]}}x, (%e{{([a-d]x)|(sp)}})
    120 
    121 ; The this pointer goes to ECX.
    122 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %ecx
    123 ; WIN32-NEXT: calll "?foo@C5@@QAE?AUS5@@XZ"
    124 ; WIN32:      ret
    125   ret void
    126 }
    127