1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=i686-windows | FileCheck %s -check-prefix=NORMAL 2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=i686-windows -no-x86-call-frame-opt | FileCheck %s -check-prefix=NOPUSH 3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-windows | FileCheck %s -check-prefix=X64 4*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=i686-windows -stackrealign -stack-alignment=32 | FileCheck %s -check-prefix=ALIGNED 5*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s -check-prefix=LINUX 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker%class.Class = type { i32 } 8*9880d681SAndroid Build Coastguard Worker%struct.s = type { i64 } 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Workerdeclare void @good(i32 %a, i32 %b, i32 %c, i32 %d) 11*9880d681SAndroid Build Coastguard Workerdeclare void @inreg(i32 %a, i32 inreg %b, i32 %c, i32 %d) 12*9880d681SAndroid Build Coastguard Workerdeclare x86_thiscallcc void @thiscall(%class.Class* %class, i32 %a, i32 %b, i32 %c, i32 %d) 13*9880d681SAndroid Build Coastguard Workerdeclare void @oneparam(i32 %a) 14*9880d681SAndroid Build Coastguard Workerdeclare void @eightparams(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) 15*9880d681SAndroid Build Coastguard Workerdeclare void @struct(%struct.s* byval %a, i32 %b, i32 %c, i32 %d) 16*9880d681SAndroid Build Coastguard Workerdeclare void @inalloca(<{ %struct.s }>* inalloca) 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.stacksave() 19*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.stackrestore(i8*) 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker; We should get pushes for x86, even though there is a reserved call frame. 22*9880d681SAndroid Build Coastguard Worker; Make sure we don't touch x86-64, and that turning it off works. 23*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test1: 24*9880d681SAndroid Build Coastguard Worker; NORMAL-NOT: subl {{.*}} %esp 25*9880d681SAndroid Build Coastguard Worker; NORMAL: pushl $4 26*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $3 27*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $2 28*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $1 29*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: call 30*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: addl $16, %esp 31*9880d681SAndroid Build Coastguard Worker; X64-LABEL: test1: 32*9880d681SAndroid Build Coastguard Worker; X64: movl $1, %ecx 33*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movl $2, %edx 34*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movl $3, %r8d 35*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movl $4, %r9d 36*9880d681SAndroid Build Coastguard Worker; X64-NEXT: callq good 37*9880d681SAndroid Build Coastguard Worker; NOPUSH-LABEL: test1: 38*9880d681SAndroid Build Coastguard Worker; NOPUSH: subl $16, %esp 39*9880d681SAndroid Build Coastguard Worker; NOPUSH-NEXT: movl $4, 12(%esp) 40*9880d681SAndroid Build Coastguard Worker; NOPUSH-NEXT: movl $3, 8(%esp) 41*9880d681SAndroid Build Coastguard Worker; NOPUSH-NEXT: movl $2, 4(%esp) 42*9880d681SAndroid Build Coastguard Worker; NOPUSH-NEXT: movl $1, (%esp) 43*9880d681SAndroid Build Coastguard Worker; NOPUSH-NEXT: call 44*9880d681SAndroid Build Coastguard Worker; NOPUSH-NEXT: addl $16, %esp 45*9880d681SAndroid Build Coastguard Workerdefine void @test1() { 46*9880d681SAndroid Build Coastguard Workerentry: 47*9880d681SAndroid Build Coastguard Worker call void @good(i32 1, i32 2, i32 3, i32 4) 48*9880d681SAndroid Build Coastguard Worker ret void 49*9880d681SAndroid Build Coastguard Worker} 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker; If we have a reserved frame, we should have pushes 52*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test2: 53*9880d681SAndroid Build Coastguard Worker; NORMAL-NOT: subl {{.*}} %esp 54*9880d681SAndroid Build Coastguard Worker; NORMAL: pushl $4 55*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $3 56*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $2 57*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $1 58*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: call 59*9880d681SAndroid Build Coastguard Workerdefine void @test2(i32 %k) { 60*9880d681SAndroid Build Coastguard Workerentry: 61*9880d681SAndroid Build Coastguard Worker %a = alloca i32, i32 %k 62*9880d681SAndroid Build Coastguard Worker call void @good(i32 1, i32 2, i32 3, i32 4) 63*9880d681SAndroid Build Coastguard Worker ret void 64*9880d681SAndroid Build Coastguard Worker} 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker; Again, we expect a sequence of 4 immediate pushes 67*9880d681SAndroid Build Coastguard Worker; Checks that we generate the right pushes for >8bit immediates 68*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test2b: 69*9880d681SAndroid Build Coastguard Worker; NORMAL-NOT: subl {{.*}} %esp 70*9880d681SAndroid Build Coastguard Worker; NORMAL: pushl $4096 71*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $3072 72*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $2048 73*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $1024 74*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: call 75*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: addl $16, %esp 76*9880d681SAndroid Build Coastguard Workerdefine void @test2b() optsize { 77*9880d681SAndroid Build Coastguard Workerentry: 78*9880d681SAndroid Build Coastguard Worker call void @good(i32 1024, i32 2048, i32 3072, i32 4096) 79*9880d681SAndroid Build Coastguard Worker ret void 80*9880d681SAndroid Build Coastguard Worker} 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker; The first push should push a register 83*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test3: 84*9880d681SAndroid Build Coastguard Worker; NORMAL-NOT: subl {{.*}} %esp 85*9880d681SAndroid Build Coastguard Worker; NORMAL: pushl $4 86*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $3 87*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $2 88*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl %e{{..}} 89*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: call 90*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: addl $16, %esp 91*9880d681SAndroid Build Coastguard Workerdefine void @test3(i32 %k) optsize { 92*9880d681SAndroid Build Coastguard Workerentry: 93*9880d681SAndroid Build Coastguard Worker %f = add i32 %k, 1 94*9880d681SAndroid Build Coastguard Worker call void @good(i32 %f, i32 2, i32 3, i32 4) 95*9880d681SAndroid Build Coastguard Worker ret void 96*9880d681SAndroid Build Coastguard Worker} 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker; We support weird calling conventions 99*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test4: 100*9880d681SAndroid Build Coastguard Worker; NORMAL: movl $2, %eax 101*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $4 102*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $3 103*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $1 104*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: call 105*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: addl $12, %esp 106*9880d681SAndroid Build Coastguard Workerdefine void @test4() optsize { 107*9880d681SAndroid Build Coastguard Workerentry: 108*9880d681SAndroid Build Coastguard Worker call void @inreg(i32 1, i32 2, i32 3, i32 4) 109*9880d681SAndroid Build Coastguard Worker ret void 110*9880d681SAndroid Build Coastguard Worker} 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test4b: 113*9880d681SAndroid Build Coastguard Worker; NORMAL: movl 4(%esp), %ecx 114*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $4 115*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $3 116*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $2 117*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $1 118*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: call 119*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: ret 120*9880d681SAndroid Build Coastguard Workerdefine void @test4b(%class.Class* %f) optsize { 121*9880d681SAndroid Build Coastguard Workerentry: 122*9880d681SAndroid Build Coastguard Worker call x86_thiscallcc void @thiscall(%class.Class* %f, i32 1, i32 2, i32 3, i32 4) 123*9880d681SAndroid Build Coastguard Worker ret void 124*9880d681SAndroid Build Coastguard Worker} 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker; When there is no reserved call frame, check that additional alignment 127*9880d681SAndroid Build Coastguard Worker; is added when the pushes don't add up to the required alignment. 128*9880d681SAndroid Build Coastguard Worker; ALIGNED-LABEL: test5: 129*9880d681SAndroid Build Coastguard Worker; ALIGNED: subl $16, %esp 130*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: pushl $4 131*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: pushl $3 132*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: pushl $2 133*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: pushl $1 134*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: call 135*9880d681SAndroid Build Coastguard Workerdefine void @test5(i32 %k) { 136*9880d681SAndroid Build Coastguard Workerentry: 137*9880d681SAndroid Build Coastguard Worker %a = alloca i32, i32 %k 138*9880d681SAndroid Build Coastguard Worker call void @good(i32 1, i32 2, i32 3, i32 4) 139*9880d681SAndroid Build Coastguard Worker ret void 140*9880d681SAndroid Build Coastguard Worker} 141*9880d681SAndroid Build Coastguard Worker 142*9880d681SAndroid Build Coastguard Worker; When the alignment adds up, do the transformation 143*9880d681SAndroid Build Coastguard Worker; ALIGNED-LABEL: test5b: 144*9880d681SAndroid Build Coastguard Worker; ALIGNED: pushl $8 145*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: pushl $7 146*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: pushl $6 147*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: pushl $5 148*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: pushl $4 149*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: pushl $3 150*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: pushl $2 151*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: pushl $1 152*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: call 153*9880d681SAndroid Build Coastguard Workerdefine void @test5b() optsize { 154*9880d681SAndroid Build Coastguard Workerentry: 155*9880d681SAndroid Build Coastguard Worker call void @eightparams(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8) 156*9880d681SAndroid Build Coastguard Worker ret void 157*9880d681SAndroid Build Coastguard Worker} 158*9880d681SAndroid Build Coastguard Worker 159*9880d681SAndroid Build Coastguard Worker; When having to compensate for the alignment isn't worth it, 160*9880d681SAndroid Build Coastguard Worker; don't use pushes. 161*9880d681SAndroid Build Coastguard Worker; ALIGNED-LABEL: test5c: 162*9880d681SAndroid Build Coastguard Worker; ALIGNED: movl $1, (%esp) 163*9880d681SAndroid Build Coastguard Worker; ALIGNED-NEXT: call 164*9880d681SAndroid Build Coastguard Workerdefine void @test5c() optsize { 165*9880d681SAndroid Build Coastguard Workerentry: 166*9880d681SAndroid Build Coastguard Worker call void @oneparam(i32 1) 167*9880d681SAndroid Build Coastguard Worker ret void 168*9880d681SAndroid Build Coastguard Worker} 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker; Check that pushing the addresses of globals (Or generally, things that 171*9880d681SAndroid Build Coastguard Worker; aren't exactly immediates) isn't broken. 172*9880d681SAndroid Build Coastguard Worker; Fixes PR21878. 173*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test6: 174*9880d681SAndroid Build Coastguard Worker; NORMAL: pushl $_ext 175*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: call 176*9880d681SAndroid Build Coastguard Workerdeclare void @f(i8*) 177*9880d681SAndroid Build Coastguard Worker@ext = external constant i8 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Workerdefine void @test6() { 180*9880d681SAndroid Build Coastguard Worker call void @f(i8* @ext) 181*9880d681SAndroid Build Coastguard Worker br label %bb 182*9880d681SAndroid Build Coastguard Workerbb: 183*9880d681SAndroid Build Coastguard Worker alloca i32 184*9880d681SAndroid Build Coastguard Worker ret void 185*9880d681SAndroid Build Coastguard Worker} 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Worker; Check that we fold simple cases into the push 188*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test7: 189*9880d681SAndroid Build Coastguard Worker; NORMAL-NOT: subl {{.*}} %esp 190*9880d681SAndroid Build Coastguard Worker; NORMAL: movl 4(%esp), [[EAX:%e..]] 191*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $4 192*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl ([[EAX]]) 193*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $2 194*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $1 195*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: call 196*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: addl $16, %esp 197*9880d681SAndroid Build Coastguard Workerdefine void @test7(i32* %ptr) optsize { 198*9880d681SAndroid Build Coastguard Workerentry: 199*9880d681SAndroid Build Coastguard Worker %val = load i32, i32* %ptr 200*9880d681SAndroid Build Coastguard Worker call void @good(i32 1, i32 2, i32 %val, i32 4) 201*9880d681SAndroid Build Coastguard Worker ret void 202*9880d681SAndroid Build Coastguard Worker} 203*9880d681SAndroid Build Coastguard Worker 204*9880d681SAndroid Build Coastguard Worker; Fold stack-relative loads into the push, with correct offset 205*9880d681SAndroid Build Coastguard Worker; In particular, at the second push, %b was at 12(%esp) and 206*9880d681SAndroid Build Coastguard Worker; %a wast at 8(%esp), but the second push bumped %esp, so %a 207*9880d681SAndroid Build Coastguard Worker; is now it at 12(%esp) 208*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test8: 209*9880d681SAndroid Build Coastguard Worker; NORMAL: pushl $4 210*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl 12(%esp) 211*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl 12(%esp) 212*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $1 213*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: call 214*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: addl $16, %esp 215*9880d681SAndroid Build Coastguard Workerdefine void @test8(i32 %a, i32 %b) optsize { 216*9880d681SAndroid Build Coastguard Workerentry: 217*9880d681SAndroid Build Coastguard Worker call void @good(i32 1, i32 %a, i32 %b, i32 4) 218*9880d681SAndroid Build Coastguard Worker ret void 219*9880d681SAndroid Build Coastguard Worker} 220*9880d681SAndroid Build Coastguard Worker 221*9880d681SAndroid Build Coastguard Worker; If one function is using push instructions, and the other isn't 222*9880d681SAndroid Build Coastguard Worker; (because it has frame-index references), then we must resolve 223*9880d681SAndroid Build Coastguard Worker; these references correctly. 224*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test9: 225*9880d681SAndroid Build Coastguard Worker; NORMAL-NOT: leal (%esp), 226*9880d681SAndroid Build Coastguard Worker; NORMAL: pushl $4 227*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $3 228*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $2 229*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $1 230*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: call 231*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: subl $4, %esp 232*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl 20(%esp), [[E1:%e..]] 233*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl 24(%esp), [[E2:%e..]] 234*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl [[E2]], 4(%esp) 235*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl [[E1]], (%esp) 236*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: leal 32(%esp), [[E3:%e..]] 237*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl [[E3]], 16(%esp) 238*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: leal 28(%esp), [[E4:%e..]] 239*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl [[E4]], 12(%esp) 240*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl $6, 8(%esp) 241*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: call 242*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: addl $20, %esp 243*9880d681SAndroid Build Coastguard Workerdefine void @test9() optsize { 244*9880d681SAndroid Build Coastguard Workerentry: 245*9880d681SAndroid Build Coastguard Worker %p = alloca i32, align 4 246*9880d681SAndroid Build Coastguard Worker %q = alloca i32, align 4 247*9880d681SAndroid Build Coastguard Worker %s = alloca %struct.s, align 4 248*9880d681SAndroid Build Coastguard Worker call void @good(i32 1, i32 2, i32 3, i32 4) 249*9880d681SAndroid Build Coastguard Worker %pv = ptrtoint i32* %p to i32 250*9880d681SAndroid Build Coastguard Worker %qv = ptrtoint i32* %q to i32 251*9880d681SAndroid Build Coastguard Worker call void @struct(%struct.s* byval %s, i32 6, i32 %qv, i32 %pv) 252*9880d681SAndroid Build Coastguard Worker ret void 253*9880d681SAndroid Build Coastguard Worker} 254*9880d681SAndroid Build Coastguard Worker 255*9880d681SAndroid Build Coastguard Worker; We can end up with an indirect call which gets reloaded on the spot. 256*9880d681SAndroid Build Coastguard Worker; Make sure we reference the correct stack slot - we spill into (%esp) 257*9880d681SAndroid Build Coastguard Worker; and reload from 16(%esp) due to the pushes. 258*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test10: 259*9880d681SAndroid Build Coastguard Worker; NORMAL: movl $_good, [[ALLOC:.*]] 260*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl [[ALLOC]], [[EAX:%e..]] 261*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl [[EAX]], (%esp) # 4-byte Spill 262*9880d681SAndroid Build Coastguard Worker; NORMAL: nop 263*9880d681SAndroid Build Coastguard Worker; NORMAL: pushl $4 264*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $3 265*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $2 266*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $1 267*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: calll *16(%esp) 268*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: addl $24, %esp 269*9880d681SAndroid Build Coastguard Workerdefine void @test10() optsize { 270*9880d681SAndroid Build Coastguard Worker %stack_fptr = alloca void (i32, i32, i32, i32)* 271*9880d681SAndroid Build Coastguard Worker store void (i32, i32, i32, i32)* @good, void (i32, i32, i32, i32)** %stack_fptr 272*9880d681SAndroid Build Coastguard Worker %good_ptr = load volatile void (i32, i32, i32, i32)*, void (i32, i32, i32, i32)** %stack_fptr 273*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di}"() 274*9880d681SAndroid Build Coastguard Worker call void (i32, i32, i32, i32) %good_ptr(i32 1, i32 2, i32 3, i32 4) 275*9880d681SAndroid Build Coastguard Worker ret void 276*9880d681SAndroid Build Coastguard Worker} 277*9880d681SAndroid Build Coastguard Worker 278*9880d681SAndroid Build Coastguard Worker; We can't fold the load from the global into the push because of 279*9880d681SAndroid Build Coastguard Worker; interference from the store 280*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test11: 281*9880d681SAndroid Build Coastguard Worker; NORMAL: movl _the_global, [[EAX:%e..]] 282*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl $42, _the_global 283*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $4 284*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $3 285*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $2 286*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl [[EAX]] 287*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: call 288*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: addl $16, %esp 289*9880d681SAndroid Build Coastguard Worker@the_global = external global i32 290*9880d681SAndroid Build Coastguard Workerdefine void @test11() optsize { 291*9880d681SAndroid Build Coastguard Worker %myload = load i32, i32* @the_global 292*9880d681SAndroid Build Coastguard Worker store i32 42, i32* @the_global 293*9880d681SAndroid Build Coastguard Worker call void @good(i32 %myload, i32 2, i32 3, i32 4) 294*9880d681SAndroid Build Coastguard Worker ret void 295*9880d681SAndroid Build Coastguard Worker} 296*9880d681SAndroid Build Coastguard Worker 297*9880d681SAndroid Build Coastguard Worker; Converting one mov into a push isn't worth it when 298*9880d681SAndroid Build Coastguard Worker; doing so forces too much overhead for other calls. 299*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test12: 300*9880d681SAndroid Build Coastguard Worker; NORMAL: movl $8, 12(%esp) 301*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl $7, 8(%esp) 302*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl $6, 4(%esp) 303*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl $5, (%esp) 304*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: calll _good 305*9880d681SAndroid Build Coastguard Workerdefine void @test12() optsize { 306*9880d681SAndroid Build Coastguard Workerentry: 307*9880d681SAndroid Build Coastguard Worker %s = alloca %struct.s, align 4 308*9880d681SAndroid Build Coastguard Worker call void @struct(%struct.s* %s, i32 2, i32 3, i32 4) 309*9880d681SAndroid Build Coastguard Worker call void @good(i32 5, i32 6, i32 7, i32 8) 310*9880d681SAndroid Build Coastguard Worker call void @struct(%struct.s* %s, i32 10, i32 11, i32 12) 311*9880d681SAndroid Build Coastguard Worker ret void 312*9880d681SAndroid Build Coastguard Worker} 313*9880d681SAndroid Build Coastguard Worker 314*9880d681SAndroid Build Coastguard Worker; But if the gains outweigh the overhead, we should do it 315*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test12b: 316*9880d681SAndroid Build Coastguard Worker; NORMAL: pushl $4 317*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $3 318*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $2 319*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $1 320*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: calll _good 321*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: subl $4, %esp 322*9880d681SAndroid Build Coastguard Worker; NORMAL: movl $8, 16(%esp) 323*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl $7, 12(%esp) 324*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl $6, 8(%esp) 325*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: calll _struct 326*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: addl $20, %esp 327*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $12 328*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $11 329*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $10 330*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl $9 331*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: calll _good 332*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: addl $16, %esp 333*9880d681SAndroid Build Coastguard Workerdefine void @test12b() optsize { 334*9880d681SAndroid Build Coastguard Workerentry: 335*9880d681SAndroid Build Coastguard Worker %s = alloca %struct.s, align 4 336*9880d681SAndroid Build Coastguard Worker call void @good(i32 1, i32 2, i32 3, i32 4) 337*9880d681SAndroid Build Coastguard Worker call void @struct(%struct.s* %s, i32 6, i32 7, i32 8) 338*9880d681SAndroid Build Coastguard Worker call void @good(i32 9, i32 10, i32 11, i32 12) 339*9880d681SAndroid Build Coastguard Worker ret void 340*9880d681SAndroid Build Coastguard Worker} 341*9880d681SAndroid Build Coastguard Worker 342*9880d681SAndroid Build Coastguard Worker; Make sure the add does not prevent folding loads into pushes. 343*9880d681SAndroid Build Coastguard Worker; val1 and val2 will not be folded into pushes since they have 344*9880d681SAndroid Build Coastguard Worker; an additional use, but val3 should be. 345*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test13: 346*9880d681SAndroid Build Coastguard Worker; NORMAL: movl ([[P1:%e..]]), [[V1:%e..]] 347*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: movl ([[P2:%e..]]), [[V2:%e..]] 348*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: , [[ADD:%e..]] 349*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl [[ADD]] 350*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl ([[P3:%e..]]) 351*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl [[V2]] 352*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: pushl [[V1]] 353*9880d681SAndroid Build Coastguard Worker; NORMAL-NEXT: calll _good 354*9880d681SAndroid Build Coastguard Worker; NORMAL: movl [[P3]], %eax 355*9880d681SAndroid Build Coastguard Workerdefine i32* @test13(i32* inreg %ptr1, i32* inreg %ptr2, i32* inreg %ptr3) optsize { 356*9880d681SAndroid Build Coastguard Workerentry: 357*9880d681SAndroid Build Coastguard Worker %val1 = load i32, i32* %ptr1 358*9880d681SAndroid Build Coastguard Worker %val2 = load i32, i32* %ptr2 359*9880d681SAndroid Build Coastguard Worker %val3 = load i32, i32* %ptr3 360*9880d681SAndroid Build Coastguard Worker %add = add i32 %val1, %val2 361*9880d681SAndroid Build Coastguard Worker call void @good(i32 %val1, i32 %val2, i32 %val3, i32 %add) 362*9880d681SAndroid Build Coastguard Worker ret i32* %ptr3 363*9880d681SAndroid Build Coastguard Worker} 364*9880d681SAndroid Build Coastguard Worker 365*9880d681SAndroid Build Coastguard Worker; Make sure to fold adjacent stack adjustments. 366*9880d681SAndroid Build Coastguard Worker; LINUX-LABEL: pr27140: 367*9880d681SAndroid Build Coastguard Worker; LINUX: subl $12, %esp 368*9880d681SAndroid Build Coastguard Worker; LINUX: .cfi_def_cfa_offset 16 369*9880d681SAndroid Build Coastguard Worker; LINUX-NOT: sub 370*9880d681SAndroid Build Coastguard Worker; LINUX: pushl $4 371*9880d681SAndroid Build Coastguard Worker; LINUX: .cfi_adjust_cfa_offset 4 372*9880d681SAndroid Build Coastguard Worker; LINUX: pushl $3 373*9880d681SAndroid Build Coastguard Worker; LINUX: .cfi_adjust_cfa_offset 4 374*9880d681SAndroid Build Coastguard Worker; LINUX: pushl $2 375*9880d681SAndroid Build Coastguard Worker; LINUX: .cfi_adjust_cfa_offset 4 376*9880d681SAndroid Build Coastguard Worker; LINUX: pushl $1 377*9880d681SAndroid Build Coastguard Worker; LINUX: .cfi_adjust_cfa_offset 4 378*9880d681SAndroid Build Coastguard Worker; LINUX: calll good 379*9880d681SAndroid Build Coastguard Worker; LINUX: addl $28, %esp 380*9880d681SAndroid Build Coastguard Worker; LINUX: .cfi_adjust_cfa_offset -16 381*9880d681SAndroid Build Coastguard Worker; LINUX-NOT: add 382*9880d681SAndroid Build Coastguard Worker; LINUX: retl 383*9880d681SAndroid Build Coastguard Workerdefine void @pr27140() optsize { 384*9880d681SAndroid Build Coastguard Workerentry: 385*9880d681SAndroid Build Coastguard Worker tail call void @good(i32 1, i32 2, i32 3, i32 4) 386*9880d681SAndroid Build Coastguard Worker ret void 387*9880d681SAndroid Build Coastguard Worker} 388*9880d681SAndroid Build Coastguard Worker 389*9880d681SAndroid Build Coastguard Worker; Check that a stack restore (leal -4(%ebp), %esp) doesn't get merged with a 390*9880d681SAndroid Build Coastguard Worker; stack adjustment (addl $12, %esp). Just because it's a lea doesn't mean it's 391*9880d681SAndroid Build Coastguard Worker; simply decreasing the stack pointer. 392*9880d681SAndroid Build Coastguard Worker; NORMAL-LABEL: test14: 393*9880d681SAndroid Build Coastguard Worker; NORMAL: calll _B_func 394*9880d681SAndroid Build Coastguard Worker; NORMAL: leal -4(%ebp), %esp 395*9880d681SAndroid Build Coastguard Worker; NORMAL-NOT: %esp 396*9880d681SAndroid Build Coastguard Worker; NORMAL: retl 397*9880d681SAndroid Build Coastguard Worker%struct.A = type { i32, i32 } 398*9880d681SAndroid Build Coastguard Worker%struct.B = type { i8 } 399*9880d681SAndroid Build Coastguard Workerdeclare x86_thiscallcc %struct.B* @B_ctor(%struct.B* returned, %struct.A* byval) 400*9880d681SAndroid Build Coastguard Workerdeclare void @B_func(%struct.B* sret, %struct.B*, i32) 401*9880d681SAndroid Build Coastguard Workerdefine void @test14(%struct.A* %a) { 402*9880d681SAndroid Build Coastguard Workerentry: 403*9880d681SAndroid Build Coastguard Worker %ref.tmp = alloca %struct.B, align 1 404*9880d681SAndroid Build Coastguard Worker %agg.tmp = alloca i64, align 4 405*9880d681SAndroid Build Coastguard Worker %tmpcast = bitcast i64* %agg.tmp to %struct.A* 406*9880d681SAndroid Build Coastguard Worker %tmp = alloca %struct.B, align 1 407*9880d681SAndroid Build Coastguard Worker %0 = bitcast %struct.A* %a to i64* 408*9880d681SAndroid Build Coastguard Worker %1 = load i64, i64* %0, align 4 409*9880d681SAndroid Build Coastguard Worker store i64 %1, i64* %agg.tmp, align 4 410*9880d681SAndroid Build Coastguard Worker %call = call x86_thiscallcc %struct.B* @B_ctor(%struct.B* %ref.tmp, %struct.A* byval %tmpcast) 411*9880d681SAndroid Build Coastguard Worker %2 = getelementptr inbounds %struct.B, %struct.B* %tmp, i32 0, i32 0 412*9880d681SAndroid Build Coastguard Worker call void @B_func(%struct.B* sret %tmp, %struct.B* %ref.tmp, i32 1) 413*9880d681SAndroid Build Coastguard Worker ret void 414*9880d681SAndroid Build Coastguard Worker} 415