Index: llvm/lib/Target/ARM/ARMFrameLowering.cpp =================================================================== --- llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -1229,19 +1229,16 @@ // The aligned reloads from area DPRCS2 are not inserted here. if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs) continue; - if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt && - !isCmseEntry && !isTrap && STI.hasV5TOps()) { - if (MBB.succ_empty()) { - Reg = ARM::PC; - // Fold the return instruction into the LDM. - DeleteRet = true; - LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET; - // We 'restore' LR into PC so it is not live out of the return block: - // Clear Restored bit. - Info.setRestored(false); - } else - LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD; + !isCmseEntry && !isTrap && AFI->getArgumentStackToRestore() == 0 && + STI.hasV5TOps() && MBB.succ_empty()) { + Reg = ARM::PC; + // Fold the return instruction into the LDM. + DeleteRet = true; + LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET; + // We 'restore' LR into PC so it is not live out of the return block: + // Clear Restored bit. + Info.setRestored(false); } // If NoGap is true, pop consecutive registers and then leave the rest Index: llvm/test/CodeGen/ARM/tailcc-call.ll =================================================================== --- llvm/test/CodeGen/ARM/tailcc-call.ll +++ llvm/test/CodeGen/ARM/tailcc-call.ll @@ -191,3 +191,15 @@ call void @Ccallee_stack4([4 x i32] undef, i32 42) ret void } + +; Don't try to return by popping pc if there's stack to reclaim. +define tailcc void @notail_stackclean([4 x i32], i32) { +; COMMON-LABEL: notail_stackclean: +; COMMON: pop {r7, lr} +; COMMON: add sp, #8 +; COMMON: bx lr + + + call void @callee_stack0() + ret void +}