Index: lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.cpp +++ lib/Target/AArch64/AArch64InstrInfo.cpp @@ -5267,10 +5267,11 @@ void AArch64InstrInfo::insertOutlinerEpilogue( MachineBasicBlock &MBB, MachineFunction &MF, const MachineOutlinerInfo &MInfo) const { - // Is there a call in the outlined range? - if (std::any_of(MBB.instr_begin(), MBB.instr_end(), - [](MachineInstr &MI) { return MI.isCall(); })) { + auto IsNonTailCall = [](MachineInstr &MI) { + return MI.isCall() && !MI.isReturn(); + }; + if (std::any_of(MBB.instr_begin(), MBB.instr_end(), IsNonTailCall)) { // Fix up the instructions in the range, since we're going to modify the // stack. fixupPostOutline(MBB); Index: test/CodeGen/AArch64/machine-outliner-tail.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/machine-outliner-tail.ll @@ -0,0 +1,22 @@ +; RUN: llc -verify-machineinstrs -enable-machine-outliner -mtriple=aarch64-linux-gnu < %s | FileCheck %s + +; CHECK: OUTLINED_FUNCTION_0: +; CHECK: orr w0, wzr, #0x1 +; CHECK-NEXT: orr w1, wzr, #0x2 +; CHECK-NEXT: orr w2, wzr, #0x3 +; CHECK-NEXT: orr w3, wzr, #0x4 +; CHECK-NEXT: b z + +define void @a() { +entry: + tail call void @z(i32 1, i32 2, i32 3, i32 4) + ret void +} + +declare void @z(i32, i32, i32, i32) + +define dso_local void @b(i32* nocapture readnone %p) { +entry: + tail call void @z(i32 1, i32 2, i32 3, i32 4) + ret void +}