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); + + // If a stack probe will be emitted, spill R4 and LR, since they are + // clobbered by the stack probe call. + // This estimate should be a safe, conservative estimate. The actual + // stack probe is enabled based on the size of the local objects; + // this estimate also includes the varargs store size. + if (STI.isTargetWindows() && WindowsRequiresStackProbe(MF, MFI.estimateStackSize(MF))) { + 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*}}