Index: lib/Target/X86/X86TargetMachine.cpp =================================================================== --- lib/Target/X86/X86TargetMachine.cpp +++ lib/Target/X86/X86TargetMachine.cpp @@ -307,9 +307,9 @@ if (getOptLevel() != CodeGenOpt::None) { addPass(createX86FixupSetCC()); addPass(createX86OptimizeLEAs()); + addPass(createX86CallFrameOptimization()); } - addPass(createX86CallFrameOptimization()); addPass(createX86WinAllocaExpander()); } Index: test/CodeGen/X86/fast-isel-call.ll =================================================================== --- test/CodeGen/X86/fast-isel-call.ll +++ test/CodeGen/X86/fast-isel-call.ll @@ -23,12 +23,12 @@ call void @foo2(%struct.s* byval %d ) ret void ; CHECK-LABEL: test2: -; CHECK: movl (%eax), %[[reg1:e[a-d]x]] -; CHECK: movl 4(%eax), %[[reg2:e[a-d]x]] -; CHECK: movl 8(%eax), %[[reg3:e[a-d]x]] -; CHECK: pushl %[[reg3]] -; CHECK: pushl %[[reg2]] -; CHECK: pushl %[[reg1]] +; CHECK: movl (%eax), %ecx +; CHECK: movl %ecx, (%esp) +; CHECK: movl 4(%eax), %ecx +; CHECK: movl %ecx, 4(%esp) +; CHECK: movl 8(%eax), %eax +; CHECK: movl %eax, 8(%esp) } declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind Index: test/CodeGen/X86/win32_sret.ll =================================================================== --- test/CodeGen/X86/win32_sret.ll +++ test/CodeGen/X86/win32_sret.ll @@ -139,7 +139,7 @@ ; (through %ecx in the -O0 build). ; WIN32: leal {{[0-9]*}}(%esp), %e{{[a-d]}}x ; WIN32: leal {{[0-9]*}}(%esp), %ecx -; WIN32: pushl %e{{[a-d]}}x +; WIN32: {{pushl %e[a-d]x|movl %e[a-d]x, \(%esp\)}} ; WIN32-NEXT: calll "?foo@C5@@QAE?AUS5@@XZ" ; WIN32: retl ret void @@ -154,21 +154,21 @@ ; LINUX-LABEL: test6_f: ; The %x argument is moved to %ecx. It will be the this pointer. -; WIN32: movl 16(%esp), %ecx +; WIN32: movl {{16|20}}(%esp), %ecx ; The sret pointer is (%esp) -; WIN32: leal (%esp), %[[REG:e[a-d]x]] -; WIN32-NEXT: pushl %[[REG]] +; WIN32: leal {{4?}}(%esp), %eax +; WIN32-NEXT: {{pushl %eax|movl %eax, \(%esp\)}} ; The sret pointer is %ecx ; The %x argument is moved to (%esp). It will be the this pointer. -; MINGW_X86: leal (%esp), %ecx -; MINGW_X86-NEXT: pushl 16(%esp) +; MINGW_X86: leal {{4?}}(%esp), %ecx +; MINGW_X86-NEXT: {{pushl 16\(%esp\)|movl %eax, \(%esp\)}} ; MINGW_X86-NEXT: calll _test6_g -; CYGWIN: leal (%esp), %ecx -; CYGWIN-NEXT: pushl 16(%esp) +; CYGWIN: leal {{4?}}(%esp), %ecx +; CYGWIN-NEXT: {{pushl 16\(%esp\)|movl %eax, \(%esp\)}} ; CYGWIN-NEXT: calll _test6_g %tmp = alloca %struct.test6, align 4 @@ -186,17 +186,17 @@ ; LINUX-LABEL: test7_f: ; The %x argument is moved to %ecx on all OSs. It will be the this pointer. -; WIN32: movl 16(%esp), %ecx -; MINGW_X86: movl 16(%esp), %ecx -; CYGWIN: movl 16(%esp), %ecx +; WIN32: movl {{16|20}}(%esp), %ecx +; MINGW_X86: movl {{16|20}}(%esp), %ecx +; CYGWIN: movl {{16|20}}(%esp), %ecx ; The sret pointer is (%esp) -; WIN32: leal (%esp), %[[REG:e[a-d]x]] -; WIN32-NEXT: pushl %[[REG]] -; MINGW_X86: leal (%esp), %[[REG:e[a-d]x]] -; MINGW_X86-NEXT: pushl %[[REG]] -; CYGWIN: leal (%esp), %[[REG:e[a-d]x]] -; CYGWIN-NEXT: pushl %[[REG]] +; WIN32: leal {{4?}}(%esp), %eax +; WIN32-NEXT: {{pushl %eax|movl %eax, \(%esp\)}} +; MINGW_X86: leal {{4?}}(%esp), %eax +; MINGW_X86-NEXT: {{pushl %eax|movl %eax, \(%esp\)}} +; CYGWIN: leal {{4?}}(%esp), %eax +; CYGWIN-NEXT: {{pushl %eax|movl %eax, \(%esp\)}} %tmp = alloca %struct.test7, align 4 call x86_thiscallcc void @test7_g(%struct.test7* %x, %struct.test7* sret %tmp)