Index: lib/Target/ARM/ARMFrameLowering.cpp =================================================================== --- lib/Target/ARM/ARMFrameLowering.cpp +++ lib/Target/ARM/ARMFrameLowering.cpp @@ -1616,9 +1616,20 @@ // since it's not always possible to restore sp from fp in a single // instruction. // FIXME: It will be better just to find spare register here. - if (AFI->isThumb2Function() && - (MFI.hasVarSizedObjects() || RegInfo->needsStackRealignment(MF))) - SavedRegs.set(ARM::R4); + if (AFI->isThumb2Function()) { + if (MFI.hasVarSizedObjects() || RegInfo->needsStackRealignment(MF)) + SavedRegs.set(ARM::R4); + + unsigned SpillEstimate = SavedRegs.count(); + unsigned StackEstimate = MFI.estimateStackSize(MF) + 4 * SpillEstimate + 16; + + // If a stack probe will be emitted, spill R4 and LR, since they are + // clobbered by the stack probe call. + if (STI.isTargetWindows() && WindowsRequiresStackProbe(MF, StackEstimate)) { + SavedRegs.set(ARM::R4); + SavedRegs.set(ARM::LR); + } + } if (AFI->isThumb1OnlyFunction()) { // Spill LR if Thumb1 function uses variable length argument lists. Index: test/CodeGen/ARM/Windows/chkstk-movw-movt-isel.ll =================================================================== --- test/CodeGen/ARM/Windows/chkstk-movw-movt-isel.ll +++ test/CodeGen/ARM/Windows/chkstk-movw-movt-isel.ll @@ -18,7 +18,7 @@ } ; CHECK-LABEL: isel -; CHECK: push {r4, r5} +; CHECK: push {r4, r5, r6, lr} ; CHECK: movw r12, #0 ; CHECK: movt r12, #0 ; CHECK: movw r4, #{{\d*}}