1*9880d681SAndroid Build Coastguard Worker; We specify -mcpu explicitly to avoid instruction reordering that happens on 2*9880d681SAndroid Build Coastguard Worker; some setups (e.g., Atom) from affecting the output. 3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=core2 -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN32 4*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=core2 -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X86 5*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=core2 -mtriple=i686-pc-cygwin | FileCheck %s -check-prefix=CYGWIN 6*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=core2 -mtriple=i386-pc-linux | FileCheck %s -check-prefix=LINUX 7*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=core2 -O0 -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN32 8*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=core2 -O0 -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X86 9*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=core2 -O0 -mtriple=i686-pc-cygwin | FileCheck %s -check-prefix=CYGWIN 10*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=core2 -O0 -mtriple=i386-pc-linux | FileCheck %s -check-prefix=LINUX 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Worker; The SysV ABI used by most Unixes and Mingw on x86 specifies that an sret pointer 13*9880d681SAndroid Build Coastguard Worker; is callee-cleanup. However, in MSVC's cdecl calling convention, sret pointer 14*9880d681SAndroid Build Coastguard Worker; arguments are caller-cleanup like normal arguments. 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Workerdefine void @sret1(i8* sret %x) nounwind { 17*9880d681SAndroid Build Coastguard Workerentry: 18*9880d681SAndroid Build Coastguard Worker; WIN32-LABEL: _sret1: 19*9880d681SAndroid Build Coastguard Worker; WIN32: movb $42, (%eax) 20*9880d681SAndroid Build Coastguard Worker; WIN32-NOT: popl %eax 21*9880d681SAndroid Build Coastguard Worker; WIN32: {{retl$}} 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker; MINGW_X86-LABEL: _sret1: 24*9880d681SAndroid Build Coastguard Worker; MINGW_X86: {{retl$}} 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker; CYGWIN-LABEL: _sret1: 27*9880d681SAndroid Build Coastguard Worker; CYGWIN: retl $4 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Worker; LINUX-LABEL: sret1: 30*9880d681SAndroid Build Coastguard Worker; LINUX: retl $4 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %x, align 4 33*9880d681SAndroid Build Coastguard Worker ret void 34*9880d681SAndroid Build Coastguard Worker} 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Workerdefine void @sret2(i8* sret %x, i8 %y) nounwind { 37*9880d681SAndroid Build Coastguard Workerentry: 38*9880d681SAndroid Build Coastguard Worker; WIN32-LABEL: _sret2: 39*9880d681SAndroid Build Coastguard Worker; WIN32: movb {{.*}}, (%eax) 40*9880d681SAndroid Build Coastguard Worker; WIN32-NOT: popl %eax 41*9880d681SAndroid Build Coastguard Worker; WIN32: {{retl$}} 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker; MINGW_X86-LABEL: _sret2: 44*9880d681SAndroid Build Coastguard Worker; MINGW_X86: {{retl$}} 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker; CYGWIN-LABEL: _sret2: 47*9880d681SAndroid Build Coastguard Worker; CYGWIN: retl $4 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker; LINUX-LABEL: sret2: 50*9880d681SAndroid Build Coastguard Worker; LINUX: retl $4 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker store i8 %y, i8* %x 53*9880d681SAndroid Build Coastguard Worker ret void 54*9880d681SAndroid Build Coastguard Worker} 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Workerdefine void @sret3(i8* sret %x, i8* %y) nounwind { 57*9880d681SAndroid Build Coastguard Workerentry: 58*9880d681SAndroid Build Coastguard Worker; WIN32-LABEL: _sret3: 59*9880d681SAndroid Build Coastguard Worker; WIN32: movb $42, (%eax) 60*9880d681SAndroid Build Coastguard Worker; WIN32-NOT: movb $13, (%eax) 61*9880d681SAndroid Build Coastguard Worker; WIN32-NOT: popl %eax 62*9880d681SAndroid Build Coastguard Worker; WIN32: {{retl$}} 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker; MINGW_X86-LABEL: _sret3: 65*9880d681SAndroid Build Coastguard Worker; MINGW_X86: {{retl$}} 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker; CYGWIN-LABEL: _sret3: 68*9880d681SAndroid Build Coastguard Worker; CYGWIN: retl $4 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker; LINUX-LABEL: sret3: 71*9880d681SAndroid Build Coastguard Worker; LINUX: retl $4 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %x 74*9880d681SAndroid Build Coastguard Worker store i8 13, i8* %y 75*9880d681SAndroid Build Coastguard Worker ret void 76*9880d681SAndroid Build Coastguard Worker} 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker; PR15556 79*9880d681SAndroid Build Coastguard Worker%struct.S4 = type { i32, i32, i32 } 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Workerdefine void @sret4(%struct.S4* noalias sret %agg.result) { 82*9880d681SAndroid Build Coastguard Workerentry: 83*9880d681SAndroid Build Coastguard Worker; WIN32-LABEL: _sret4: 84*9880d681SAndroid Build Coastguard Worker; WIN32: movl $42, (%eax) 85*9880d681SAndroid Build Coastguard Worker; WIN32-NOT: popl %eax 86*9880d681SAndroid Build Coastguard Worker; WIN32: {{retl$}} 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker; MINGW_X86-LABEL: _sret4: 89*9880d681SAndroid Build Coastguard Worker; MINGW_X86: {{retl$}} 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Worker; CYGWIN-LABEL: _sret4: 92*9880d681SAndroid Build Coastguard Worker; CYGWIN: retl $4 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard Worker; LINUX-LABEL: sret4: 95*9880d681SAndroid Build Coastguard Worker; LINUX: retl $4 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Worker %x = getelementptr inbounds %struct.S4, %struct.S4* %agg.result, i32 0, i32 0 98*9880d681SAndroid Build Coastguard Worker store i32 42, i32* %x, align 4 99*9880d681SAndroid Build Coastguard Worker ret void 100*9880d681SAndroid Build Coastguard Worker} 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Worker%struct.S5 = type { i32 } 103*9880d681SAndroid Build Coastguard Worker%class.C5 = type { i8 } 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Workerdefine x86_thiscallcc void @"\01?foo@C5@@QAE?AUS5@@XZ"(%struct.S5* noalias sret %agg.result, %class.C5* %this) { 106*9880d681SAndroid Build Coastguard Workerentry: 107*9880d681SAndroid Build Coastguard Worker %this.addr = alloca %class.C5*, align 4 108*9880d681SAndroid Build Coastguard Worker store %class.C5* %this, %class.C5** %this.addr, align 4 109*9880d681SAndroid Build Coastguard Worker %this1 = load %class.C5*, %class.C5** %this.addr 110*9880d681SAndroid Build Coastguard Worker %x = getelementptr inbounds %struct.S5, %struct.S5* %agg.result, i32 0, i32 0 111*9880d681SAndroid Build Coastguard Worker store i32 42, i32* %x, align 4 112*9880d681SAndroid Build Coastguard Worker ret void 113*9880d681SAndroid Build Coastguard Worker; WIN32-LABEL: {{^}}"?foo@C5@@QAE?AUS5@@XZ": 114*9880d681SAndroid Build Coastguard Worker; MINGW_X86-LABEL: {{^}}"?foo@C5@@QAE?AUS5@@XZ": 115*9880d681SAndroid Build Coastguard Worker; CYGWIN-LABEL: {{^}}"?foo@C5@@QAE?AUS5@@XZ": 116*9880d681SAndroid Build Coastguard Worker; LINUX-LABEL: {{^}}"?foo@C5@@QAE?AUS5@@XZ": 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker; The address of the return structure is passed as an implicit parameter. 119*9880d681SAndroid Build Coastguard Worker; In the -O0 build, %eax is spilled at the beginning of the function, hence we 120*9880d681SAndroid Build Coastguard Worker; should match both 4(%esp) and 8(%esp). 121*9880d681SAndroid Build Coastguard Worker; WIN32: {{[48]}}(%esp), %eax 122*9880d681SAndroid Build Coastguard Worker; WIN32: movl $42, (%eax) 123*9880d681SAndroid Build Coastguard Worker; WIN32: retl $4 124*9880d681SAndroid Build Coastguard Worker} 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Workerdefine void @call_foo5() { 127*9880d681SAndroid Build Coastguard Workerentry: 128*9880d681SAndroid Build Coastguard Worker %c = alloca %class.C5, align 1 129*9880d681SAndroid Build Coastguard Worker %s = alloca %struct.S5, align 4 130*9880d681SAndroid Build Coastguard Worker call x86_thiscallcc void @"\01?foo@C5@@QAE?AUS5@@XZ"(%struct.S5* sret %s, %class.C5* %c) 131*9880d681SAndroid Build Coastguard Worker; WIN32-LABEL: {{^}}_call_foo5: 132*9880d681SAndroid Build Coastguard Worker; MINGW_X86-LABEL: {{^}}_call_foo5: 133*9880d681SAndroid Build Coastguard Worker; CYGWIN-LABEL: {{^}}_call_foo5: 134*9880d681SAndroid Build Coastguard Worker; LINUX-LABEL: {{^}}call_foo5: 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Worker; Load the address of the result and put it onto stack 138*9880d681SAndroid Build Coastguard Worker; The this pointer goes to ECX. 139*9880d681SAndroid Build Coastguard Worker; (through %ecx in the -O0 build). 140*9880d681SAndroid Build Coastguard Worker; WIN32: leal {{[0-9]*}}(%esp), %e{{[a-d]}}x 141*9880d681SAndroid Build Coastguard Worker; WIN32: leal {{[0-9]*}}(%esp), %ecx 142*9880d681SAndroid Build Coastguard Worker; WIN32: {{pushl %e[a-d]x|movl %e[a-d]x, \(%esp\)}} 143*9880d681SAndroid Build Coastguard Worker; WIN32-NEXT: calll "?foo@C5@@QAE?AUS5@@XZ" 144*9880d681SAndroid Build Coastguard Worker; WIN32: retl 145*9880d681SAndroid Build Coastguard Worker ret void 146*9880d681SAndroid Build Coastguard Worker} 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker%struct.test6 = type { i32, i32, i32 } 150*9880d681SAndroid Build Coastguard Workerdefine void @test6_f(%struct.test6* %x) nounwind { 151*9880d681SAndroid Build Coastguard Worker; WIN32-LABEL: _test6_f: 152*9880d681SAndroid Build Coastguard Worker; MINGW_X86-LABEL: _test6_f: 153*9880d681SAndroid Build Coastguard Worker; CYGWIN-LABEL: _test6_f: 154*9880d681SAndroid Build Coastguard Worker; LINUX-LABEL: test6_f: 155*9880d681SAndroid Build Coastguard Worker 156*9880d681SAndroid Build Coastguard Worker; The %x argument is moved to %ecx. It will be the this pointer. 157*9880d681SAndroid Build Coastguard Worker; WIN32: movl {{16|20}}(%esp), %ecx 158*9880d681SAndroid Build Coastguard Worker 159*9880d681SAndroid Build Coastguard Worker 160*9880d681SAndroid Build Coastguard Worker; The sret pointer is (%esp) 161*9880d681SAndroid Build Coastguard Worker; WIN32: leal {{4?}}(%esp), %eax 162*9880d681SAndroid Build Coastguard Worker; WIN32-NEXT: {{pushl %eax|movl %eax, \(%esp\)}} 163*9880d681SAndroid Build Coastguard Worker 164*9880d681SAndroid Build Coastguard Worker; The sret pointer is %ecx 165*9880d681SAndroid Build Coastguard Worker; The %x argument is moved to (%esp). It will be the this pointer. 166*9880d681SAndroid Build Coastguard Worker; MINGW_X86: leal {{4?}}(%esp), %ecx 167*9880d681SAndroid Build Coastguard Worker; MINGW_X86-NEXT: {{pushl 16\(%esp\)|movl %eax, \(%esp\)}} 168*9880d681SAndroid Build Coastguard Worker; MINGW_X86-NEXT: calll _test6_g 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker; CYGWIN: leal {{4?}}(%esp), %ecx 171*9880d681SAndroid Build Coastguard Worker; CYGWIN-NEXT: {{pushl 16\(%esp\)|movl %eax, \(%esp\)}} 172*9880d681SAndroid Build Coastguard Worker; CYGWIN-NEXT: calll _test6_g 173*9880d681SAndroid Build Coastguard Worker 174*9880d681SAndroid Build Coastguard Worker %tmp = alloca %struct.test6, align 4 175*9880d681SAndroid Build Coastguard Worker call x86_thiscallcc void @test6_g(%struct.test6* sret %tmp, %struct.test6* %x) 176*9880d681SAndroid Build Coastguard Worker ret void 177*9880d681SAndroid Build Coastguard Worker} 178*9880d681SAndroid Build Coastguard Workerdeclare x86_thiscallcc void @test6_g(%struct.test6* sret, %struct.test6*) 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Worker; Flipping the parameters at the IR level generates the same code. 181*9880d681SAndroid Build Coastguard Worker%struct.test7 = type { i32, i32, i32 } 182*9880d681SAndroid Build Coastguard Workerdefine void @test7_f(%struct.test7* %x) nounwind { 183*9880d681SAndroid Build Coastguard Worker; WIN32-LABEL: _test7_f: 184*9880d681SAndroid Build Coastguard Worker; MINGW_X86-LABEL: _test7_f: 185*9880d681SAndroid Build Coastguard Worker; CYGWIN-LABEL: _test7_f: 186*9880d681SAndroid Build Coastguard Worker; LINUX-LABEL: test7_f: 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Worker; The %x argument is moved to %ecx on all OSs. It will be the this pointer. 189*9880d681SAndroid Build Coastguard Worker; WIN32: movl {{16|20}}(%esp), %ecx 190*9880d681SAndroid Build Coastguard Worker; MINGW_X86: movl {{16|20}}(%esp), %ecx 191*9880d681SAndroid Build Coastguard Worker; CYGWIN: movl {{16|20}}(%esp), %ecx 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Worker; The sret pointer is (%esp) 194*9880d681SAndroid Build Coastguard Worker; WIN32: leal {{4?}}(%esp), %eax 195*9880d681SAndroid Build Coastguard Worker; WIN32-NEXT: {{pushl %eax|movl %eax, \(%esp\)}} 196*9880d681SAndroid Build Coastguard Worker; MINGW_X86: leal {{4?}}(%esp), %eax 197*9880d681SAndroid Build Coastguard Worker; MINGW_X86-NEXT: {{pushl %eax|movl %eax, \(%esp\)}} 198*9880d681SAndroid Build Coastguard Worker; CYGWIN: leal {{4?}}(%esp), %eax 199*9880d681SAndroid Build Coastguard Worker; CYGWIN-NEXT: {{pushl %eax|movl %eax, \(%esp\)}} 200*9880d681SAndroid Build Coastguard Worker 201*9880d681SAndroid Build Coastguard Worker %tmp = alloca %struct.test7, align 4 202*9880d681SAndroid Build Coastguard Worker call x86_thiscallcc void @test7_g(%struct.test7* %x, %struct.test7* sret %tmp) 203*9880d681SAndroid Build Coastguard Worker ret void 204*9880d681SAndroid Build Coastguard Worker} 205*9880d681SAndroid Build Coastguard Worker 206*9880d681SAndroid Build Coastguard Workerdefine x86_thiscallcc void @test7_g(%struct.test7* %in, %struct.test7* sret %out) { 207*9880d681SAndroid Build Coastguard Worker %s = getelementptr %struct.test7, %struct.test7* %in, i32 0, i32 0 208*9880d681SAndroid Build Coastguard Worker %d = getelementptr %struct.test7, %struct.test7* %out, i32 0, i32 0 209*9880d681SAndroid Build Coastguard Worker %v = load i32, i32* %s 210*9880d681SAndroid Build Coastguard Worker store i32 %v, i32* %d 211*9880d681SAndroid Build Coastguard Worker call void @clobber_eax() 212*9880d681SAndroid Build Coastguard Worker ret void 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Worker; Make sure we return the second parameter in %eax. 215*9880d681SAndroid Build Coastguard Worker; WIN32-LABEL: _test7_g: 216*9880d681SAndroid Build Coastguard Worker; WIN32: calll _clobber_eax 217*9880d681SAndroid Build Coastguard Worker; WIN32: movl {{.*}}, %eax 218*9880d681SAndroid Build Coastguard Worker; WIN32: retl 219*9880d681SAndroid Build Coastguard Worker} 220*9880d681SAndroid Build Coastguard Worker 221*9880d681SAndroid Build Coastguard Workerdeclare void @clobber_eax() 222*9880d681SAndroid Build Coastguard Worker 223*9880d681SAndroid Build Coastguard Worker; Test what happens if the first parameter has to be split by codegen. 224*9880d681SAndroid Build Coastguard Worker; Realistically, no frontend will generate code like this, but here it is for 225*9880d681SAndroid Build Coastguard Worker; completeness. 226*9880d681SAndroid Build Coastguard Workerdefine void @test8_f(i64 inreg %a, i64* sret %out) { 227*9880d681SAndroid Build Coastguard Worker store i64 %a, i64* %out 228*9880d681SAndroid Build Coastguard Worker call void @clobber_eax() 229*9880d681SAndroid Build Coastguard Worker ret void 230*9880d681SAndroid Build Coastguard Worker 231*9880d681SAndroid Build Coastguard Worker; WIN32-LABEL: _test8_f: 232*9880d681SAndroid Build Coastguard Worker; WIN32: movl {{[0-9]+}}(%esp), %[[out:[a-z]+]] 233*9880d681SAndroid Build Coastguard Worker; WIN32-DAG: movl %edx, 4(%[[out]]) 234*9880d681SAndroid Build Coastguard Worker; WIN32-DAG: movl %eax, (%[[out]]) 235*9880d681SAndroid Build Coastguard Worker; WIN32: calll _clobber_eax 236*9880d681SAndroid Build Coastguard Worker; WIN32: movl {{.*}}, %eax 237*9880d681SAndroid Build Coastguard Worker; WIN32: retl 238*9880d681SAndroid Build Coastguard Worker} 239