From 3977b77a6bb780b02559530a96597cdb1c0a5bf6 Mon Sep 17 00:00:00 2001 From: Zequan Wu Date: Thu, 23 Mar 2023 14:42:23 -0400 Subject: [PATCH] [CodeGen] Fix nomerge attribute not working in tail calls. In D79537, `nomerge` was made to only apply to non-tail calls. This fixes it by also applying it to tail calls. For ARM, I only made the new MI to inherit the flag under `TCRETURNdi` and `TCRETURNri`, because that's the place tail calls got replaced. Not sure if there's any other place needed. Fixes #61545. Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D146749 --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 1 + llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp | 3 +++ llvm/lib/Target/ARM/ARMISelLowering.cpp | 1 + llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp | 4 +++- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 4 +++- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 +++- llvm/lib/Target/SystemZ/SystemZISelLowering.cpp | 7 +++++-- llvm/lib/Target/X86/X86ISelLowering.cpp | 1 + llvm/test/CodeGen/AArch64/nomerge.ll | 4 ++++ llvm/test/CodeGen/ARM/nomerge.ll | 4 ++++ llvm/test/CodeGen/LoongArch/nomerge.ll | 4 ++++ llvm/test/CodeGen/RISCV/nomerge.ll | 4 ++++ llvm/test/CodeGen/SystemZ/nomerge.ll | 2 ++ llvm/test/CodeGen/X86/nomerge.ll | 2 ++ 14 files changed, 40 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 0fb8e4245d48e..818fe49d1717e 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -7599,6 +7599,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI, 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 index dc75f61a10e99..53c575fb73d9d 100644 --- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -2171,6 +2171,9 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, // 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 index 0bbd4dde69ae7..2b7f989fbf4bc 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -2857,6 +2857,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 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 index 2baaa591c35c1..a8c4dc4762ee5 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -2638,7 +2638,9 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI, 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 index f0dfecfb69582..a9add37197a8c 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -5629,7 +5629,9 @@ SDValue PPCTargetLowering::FinishCall( 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 index 1e137868bf37c..02c772b604ba1 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -14671,7 +14671,9 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI, 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 index f258dfc809465..e709474382e71 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1849,8 +1849,11 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI, // 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 index b479050879064..b5bb95d22912a 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -4984,6 +4984,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 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 index 7ff0abf628750..47c7fa59ed9e9 100644 --- a/llvm/test/CodeGen/AArch64/nomerge.ll +++ b/llvm/test/CodeGen/AArch64/nomerge.ll @@ -41,6 +41,10 @@ if.end3: 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 index cdfb40d44c445..8049b9d651e59 100644 --- a/llvm/test/CodeGen/ARM/nomerge.ll +++ b/llvm/test/CodeGen/ARM/nomerge.ll @@ -42,6 +42,10 @@ define void @foo_tail(i1 %i) nounwind { ; 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 index 2cf16de777428..e2dfe824284ef 100644 --- a/llvm/test/CodeGen/LoongArch/nomerge.ll +++ b/llvm/test/CodeGen/LoongArch/nomerge.ll @@ -44,6 +44,10 @@ 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: 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 index 830b3306bfeb1..f4e50b6697aef 100644 --- a/llvm/test/CodeGen/RISCV/nomerge.ll +++ b/llvm/test/CodeGen/RISCV/nomerge.ll @@ -44,6 +44,10 @@ 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 index 7b8584b958c85..d47befa668b75 100644 --- a/llvm/test/CodeGen/SystemZ/nomerge.ll +++ b/llvm/test/CodeGen/SystemZ/nomerge.ll @@ -41,6 +41,8 @@ define void @foo_tail(i1 %i) nounwind { ; 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 index 70a4e98dc98be..efbadf5b6911f 100644 --- a/llvm/test/CodeGen/X86/nomerge.ll +++ b/llvm/test/CodeGen/X86/nomerge.ll @@ -42,6 +42,8 @@ define void @foo_tail(i1 %i) nounwind { ; 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