diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index c09879fd9c2be..d3f896435862c 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -6587,6 +6587,10 @@ void ARMBaseInstrInfo::buildOutlinedFrame( // For thunk outlining, rewrite the last instruction from a call to a // tail-call. if (OF.FrameConstructionID == MachineOutlinerThunk) { + // LR is used by the tail call. + if (!MBB.isLiveIn(ARM::LR)) + MBB.addLiveIn(ARM::LR); + MachineInstr *Call = &*--MBB.instr_end(); bool isThumb = Subtarget.isThumb(); unsigned FuncOp = isThumb ? 2 : 0; diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 812b5730875d5..3e0df3afccb10 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -2668,7 +2668,7 @@ def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func", // Tail calls. -let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in { +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP,LR] in { def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, i32imm:$SPDiff), IIC_Br, []>, Sched<[WriteBr]>; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index acd46e8093aa7..0b1ae71b5bcb4 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -4035,7 +4035,7 @@ def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br, // Windows SEH unwinding also needs a strict t2 branch for tail calls. let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { // IOS version. - let Uses = [SP] in + let Uses = [SP,LR] in def tTAILJMPd: tPseudoExpand<(outs), (ins thumb_br_target:$dst, pred:$p), 4, IIC_Br, [], diff --git a/llvm/test/CodeGen/Thumb2/outlined-fn-may-clobber-lr-in-caller.ll b/llvm/test/CodeGen/Thumb2/outlined-fn-may-clobber-lr-in-caller.ll index d81d008b44bed..a9e59cecfc241 100644 --- a/llvm/test/CodeGen/Thumb2/outlined-fn-may-clobber-lr-in-caller.ll +++ b/llvm/test/CodeGen/Thumb2/outlined-fn-may-clobber-lr-in-caller.ll @@ -16,6 +16,8 @@ target datalayout = "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" define void @test(ptr nocapture noundef writeonly %arg, i32 noundef %arg1, i8 noundef zeroext %arg2) unnamed_addr #0 { ; CHECK-LABEL: test: ; CHECK: @ %bb.0: @ %bb +; CHECK-NEXT: .save {r7, lr} +; CHECK-NEXT: push {r7, lr} ; CHECK-NEXT: cmp r1, #2 ; CHECK-NEXT: beq .LBB0_3 ; CHECK-NEXT: @ %bb.1: @ %bb @@ -32,10 +34,9 @@ define void @test(ptr nocapture noundef writeonly %arg, i32 noundef %arg1, i8 no ; CHECK-NEXT: add.w r1, r2, r1, lsl #2 ; CHECK-NEXT: adds r0, #4 ; CHECK-NEXT: movs r2, #30 +; CHECK-NEXT: pop.w {r7, lr} ; CHECK-NEXT: b __aeabi_memcpy ; CHECK-NEXT: .LBB0_5: @ %bb24 -; CHECK-NEXT: .save {r7, lr} -; CHECK-NEXT: push {r7, lr} ; CHECK-NEXT: bl wombat ; CHECK-NEXT: @APP ; CHECK-NEXT: @NO_APP