diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -7546,6 +7546,7 @@ if (IsCFICall) Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue()); + DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge); DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo)); return Ret; } diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp --- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -2171,6 +2171,9 @@ // Update call site info and delete the pseudo instruction TCRETURN. if (MI.isCandidateForCallSiteEntry()) MI.getMF()->moveCallSiteInfo(&MI, &*NewMI); + // Copy nomerge flag over to new instruction. + if (MI.getFlag(MachineInstr::NoMerge)) + NewMI->setFlag(MachineInstr::NoMerge); MBB.erase(MBBI); MBBI = NewMI; diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -2853,6 +2853,7 @@ if (isTailCall) { MF.getFrameInfo().setHasTailCall(); SDValue Ret = DAG.getNode(ARMISD::TC_RETURN, dl, NodeTys, Ops); + DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge); DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo)); return Ret; } diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -2638,7 +2638,9 @@ if (IsTailCall) { MF.getFrameInfo().setHasTailCall(); - return DAG.getNode(LoongArchISD::TAIL, DL, NodeTys, Ops); + SDValue Ret = DAG.getNode(LoongArchISD::TAIL, DL, NodeTys, Ops); + DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge); + return Ret; } Chain = DAG.getNode(LoongArchISD::CALL, DL, NodeTys, Ops); diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -5629,7 +5629,9 @@ assert(CallOpc == PPCISD::TC_RETURN && "Unexpected call opcode for a tail call."); DAG.getMachineFunction().getFrameInfo().setHasTailCall(); - return DAG.getNode(CallOpc, dl, MVT::Other, Ops); + SDValue Ret = DAG.getNode(CallOpc, dl, MVT::Other, Ops); + DAG.addNoMergeSiteInfo(Ret.getNode(), CFlags.NoMerge); + return Ret; } std::array ReturnTypes = {{MVT::Other, MVT::Glue}}; diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -13767,7 +13767,9 @@ if (IsTailCall) { MF.getFrameInfo().setHasTailCall(); - return DAG.getNode(RISCVISD::TAIL, DL, NodeTys, Ops); + SDValue Ret = DAG.getNode(RISCVISD::TAIL, DL, NodeTys, Ops); + DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge); + return Ret; } Chain = DAG.getNode(RISCVISD::CALL, DL, NodeTys, Ops); diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1849,8 +1849,11 @@ // Emit the call. SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); - if (IsTailCall) - return DAG.getNode(SystemZISD::SIBCALL, DL, NodeTys, Ops); + if (IsTailCall) { + SDValue Ret = DAG.getNode(SystemZISD::SIBCALL, DL, NodeTys, Ops); + DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge); + return Ret; + } Chain = DAG.getNode(SystemZISD::CALL, DL, NodeTys, Ops); DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge); Glue = Chain.getValue(1); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -4969,6 +4969,7 @@ if (IsCFICall) Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue()); + DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge); DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo)); return Ret; } diff --git a/llvm/test/CodeGen/AArch64/nomerge.ll b/llvm/test/CodeGen/AArch64/nomerge.ll --- a/llvm/test/CodeGen/AArch64/nomerge.ll +++ b/llvm/test/CodeGen/AArch64/nomerge.ll @@ -41,6 +41,10 @@ define void @foo_tail(i1 %i) nounwind { ; CHECK-LABEL: foo_tail: ; CHECK: // %bb.0: // %entry +; CHECK-NEXT: tbz w0, #0, .LBB1_2 +; CHECK-NEXT: // %bb.1: // %if.then +; CHECK-NEXT: b bar +; CHECK-NEXT: .LBB1_2: // %if.else ; CHECK-NEXT: b bar entry: br i1 %i, label %if.then, label %if.else diff --git a/llvm/test/CodeGen/ARM/nomerge.ll b/llvm/test/CodeGen/ARM/nomerge.ll --- a/llvm/test/CodeGen/ARM/nomerge.ll +++ b/llvm/test/CodeGen/ARM/nomerge.ll @@ -42,6 +42,10 @@ ; CHECK-LABEL: foo_tail: ; CHECK: @ %bb.0: @ %entry ; CHECK-NEXT: tst r0, #1 +; CHECK-NEXT: beq .LBB1_2 +; CHECK-NEXT: @ %bb.1: @ %if.then +; CHECK-NEXT: b bar +; CHECK-NEXT: .LBB1_2: @ %if.else ; CHECK-NEXT: b bar entry: br i1 %i, label %if.then, label %if.else diff --git a/llvm/test/CodeGen/LoongArch/nomerge.ll b/llvm/test/CodeGen/LoongArch/nomerge.ll --- a/llvm/test/CodeGen/LoongArch/nomerge.ll +++ b/llvm/test/CodeGen/LoongArch/nomerge.ll @@ -44,6 +44,10 @@ ; CHECK-LABEL: foo_tail: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: andi $a0, $a0, 1 +; CHECK-NEXT: beqz $a0, .LBB1_2 +; CHECK-NEXT: # %bb.1: # %if.then +; CHECK-NEXT: b %plt(bar) +; CHECK-NEXT: .LBB1_2: # %if.else ; CHECK-NEXT: b %plt(bar) entry: br i1 %i, label %if.then, label %if.else diff --git a/llvm/test/CodeGen/RISCV/nomerge.ll b/llvm/test/CodeGen/RISCV/nomerge.ll --- a/llvm/test/CodeGen/RISCV/nomerge.ll +++ b/llvm/test/CodeGen/RISCV/nomerge.ll @@ -40,10 +40,14 @@ ret void } -define void @foo_tail(i1 %i) nounwind { +define void @foo_tail(i1 %i) nounwind{ ; CHECK-LABEL: foo_tail: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: andi a0, a0, 1 +; CHECK-NEXT: beqz a0, .LBB1_2 +; CHECK-NEXT: # %bb.1: # %if.then +; CHECK-NEXT: tail bar@plt +; CHECK-NEXT: .LBB1_2: # %if.else ; CHECK-NEXT: tail bar@plt entry: br i1 %i, label %if.then, label %if.else diff --git a/llvm/test/CodeGen/SystemZ/nomerge.ll b/llvm/test/CodeGen/SystemZ/nomerge.ll --- a/llvm/test/CodeGen/SystemZ/nomerge.ll +++ b/llvm/test/CodeGen/SystemZ/nomerge.ll @@ -41,6 +41,8 @@ ; CHECK-LABEL: foo_tail: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: tmll %r2, 1 +; CHECK-NEXT: jge bar@PLT +; CHECK-NEXT: .LBB1_1: # %if.then ; CHECK-NEXT: jg bar@PLT entry: br i1 %i, label %if.then, label %if.else diff --git a/llvm/test/CodeGen/X86/nomerge.ll b/llvm/test/CodeGen/X86/nomerge.ll --- a/llvm/test/CodeGen/X86/nomerge.ll +++ b/llvm/test/CodeGen/X86/nomerge.ll @@ -42,6 +42,8 @@ ; CHECK-LABEL: foo_tail: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: testb $1, %dil +; CHECK-NEXT: je bar # TAILCALL +; CHECK-NEXT: # %bb.1: # %if.then ; CHECK-NEXT: jmp bar # TAILCALL entry: br i1 %i, label %if.then, label %if.else