Skip to content

Commit 80e107c

Browse files
committed
Add NoMerge MIFlag to avoid MIR branch folding
Let the codegen recognized the nomerge attribute and disable branch folding when the attribute is given Differential Revision: https://reviews.llvm.org/D79537
1 parent 6f56a58 commit 80e107c

File tree

18 files changed

+220
-5
lines changed

18 files changed

+220
-5
lines changed

llvm/include/llvm/CodeGen/MachineInstr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ class MachineInstr
105105
// known to be exact.
106106
NoFPExcept = 1 << 14, // Instruction does not raise
107107
// floatint-point exceptions.
108+
NoMerge = 1 << 15, // Passes that drop source location info
109+
// (e.g. branch folding) should skip
110+
// this instruction.
108111
};
109112

110113
private:

llvm/include/llvm/CodeGen/SelectionDAG.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ class SelectionDAG {
278278
struct CallSiteDbgInfo {
279279
CallSiteInfo CSInfo;
280280
MDNode *HeapAllocSite = nullptr;
281+
bool NoMerge = false;
281282
};
282283

283284
DenseMap<const SDNode *, CallSiteDbgInfo> SDCallSiteDbgInfo;
@@ -1916,6 +1917,18 @@ class SelectionDAG {
19161917
return It->second.HeapAllocSite;
19171918
}
19181919

1920+
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge) {
1921+
if (NoMerge)
1922+
SDCallSiteDbgInfo[Node].NoMerge = NoMerge;
1923+
}
1924+
1925+
bool getNoMergeSiteInfo(const SDNode *Node) {
1926+
auto I = SDCallSiteDbgInfo.find(Node);
1927+
if (I == SDCallSiteDbgInfo.end())
1928+
return false;
1929+
return I->second.NoMerge;
1930+
}
1931+
19191932
/// Return the current function's default denormal handling kind for the given
19201933
/// floating point type.
19211934
DenormalMode getDenormalMode(EVT VT) const {

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3613,6 +3613,7 @@ class TargetLowering : public TargetLoweringBase {
36133613
bool IsConvergent : 1;
36143614
bool IsPatchPoint : 1;
36153615
bool IsPreallocated : 1;
3616+
bool NoMerge : 1;
36163617

36173618
// IsTailCall should be modified by implementations of
36183619
// TargetLowering::LowerCall that perform tail call conversions.
@@ -3636,7 +3637,8 @@ class TargetLowering : public TargetLoweringBase {
36363637
CallLoweringInfo(SelectionDAG &DAG)
36373638
: RetSExt(false), RetZExt(false), IsVarArg(false), IsInReg(false),
36383639
DoesNotReturn(false), IsReturnValueUsed(true), IsConvergent(false),
3639-
IsPatchPoint(false), IsPreallocated(false), DAG(DAG) {}
3640+
IsPatchPoint(false), IsPreallocated(false), NoMerge(false),
3641+
DAG(DAG) {}
36403642

36413643
CallLoweringInfo &setDebugLoc(const SDLoc &dl) {
36423644
DL = dl;
@@ -3685,7 +3687,8 @@ class TargetLowering : public TargetLoweringBase {
36853687
IsReturnValueUsed = !Call.use_empty();
36863688
RetSExt = Call.hasRetAttr(Attribute::SExt);
36873689
RetZExt = Call.hasRetAttr(Attribute::ZExt);
3688-
3690+
NoMerge = Call.hasFnAttr(Attribute::NoMerge);
3691+
36893692
Callee = Target;
36903693

36913694
CallConv = Call.getCallingConv();

llvm/lib/CodeGen/BranchFolding.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,9 @@ static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1,
348348
MBBI1->isInlineAsm()) {
349349
break;
350350
}
351+
if (MBBI1->getFlag(MachineInstr::NoMerge) ||
352+
MBBI2->getFlag(MachineInstr::NoMerge))
353+
break;
351354
++TailLen;
352355
I1 = MBBI1;
353356
I2 = MBBI2;

llvm/lib/CodeGen/MIRPrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,8 @@ void MIPrinter::print(const MachineInstr &MI) {
778778
OS << "exact ";
779779
if (MI.getFlag(MachineInstr::NoFPExcept))
780780
OS << "nofpexcept ";
781+
if (MI.getFlag(MachineInstr::NoMerge))
782+
OS << "nomerge ";
781783

782784
OS << TII->getName(MI.getOpcode());
783785
if (I < E)

llvm/lib/CodeGen/MachineInstr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,8 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
15951595
OS << "exact ";
15961596
if (getFlag(MachineInstr::NoFPExcept))
15971597
OS << "nofpexcept ";
1598+
if (getFlag(MachineInstr::NoMerge))
1599+
OS << "nomerge ";
15981600

15991601
// Print the opcode name.
16001602
if (TII)

llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,10 @@ EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
872872
DAG->getTarget().Options.EmitCallSiteInfo)
873873
MF.addCallArgsForwardingRegs(MI, DAG->getSDCallSiteInfo(Node));
874874

875+
if (DAG->getNoMergeSiteInfo(Node)) {
876+
MI->setFlag(MachineInstr::MIFlag::NoMerge);
877+
}
878+
875879
return MI;
876880
};
877881

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4541,6 +4541,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
45414541

45424542
// Returns a chain and a flag for retval copy to use.
45434543
Chain = DAG.getNode(AArch64ISD::CALL, DL, NodeTys, Ops);
4544+
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
45444545
InFlag = Chain.getValue(1);
45454546
DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
45464547

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,6 +2542,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
25422542

25432543
// Returns a chain and a flag for retval copy to use.
25442544
Chain = DAG.getNode(CallOpc, dl, NodeTys, Ops);
2545+
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
25452546
InFlag = Chain.getValue(1);
25462547
DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
25472548

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5586,6 +5586,7 @@ SDValue PPCTargetLowering::FinishCall(
55865586

55875587
std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
55885588
Chain = DAG.getNode(CallOpc, dl, ReturnTypes, Ops);
5589+
DAG.addNoMergeSiteInfo(Chain.getNode(), CFlags.NoMerge);
55895590
Glue = Chain.getValue(1);
55905591

55915592
// When performing tail call optimization the callee pops its arguments off
@@ -5667,7 +5668,8 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
56675668
isIndirectCall(Callee, DAG, Subtarget, isPatchPoint),
56685669
// hasNest
56695670
Subtarget.is64BitELFABI() &&
5670-
any_of(Outs, [](ISD::OutputArg Arg) { return Arg.Flags.isNest(); }));
5671+
any_of(Outs, [](ISD::OutputArg Arg) { return Arg.Flags.isNest(); }),
5672+
CLI.NoMerge);
56715673

56725674
if (Subtarget.isSVR4ABI() && Subtarget.isPPC64())
56735675
return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,

llvm/lib/Target/PowerPC/PPCISelLowering.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -979,12 +979,13 @@ namespace llvm {
979979
const bool IsPatchPoint : 1;
980980
const bool IsIndirect : 1;
981981
const bool HasNest : 1;
982+
const bool NoMerge : 1;
982983

983984
CallFlags(CallingConv::ID CC, bool IsTailCall, bool IsVarArg,
984-
bool IsPatchPoint, bool IsIndirect, bool HasNest)
985+
bool IsPatchPoint, bool IsIndirect, bool HasNest, bool NoMerge)
985986
: CallConv(CC), IsTailCall(IsTailCall), IsVarArg(IsVarArg),
986987
IsPatchPoint(IsPatchPoint), IsIndirect(IsIndirect),
987-
HasNest(HasNest) {}
988+
HasNest(HasNest), NoMerge(NoMerge) {}
988989
};
989990

990991
private:

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,6 +2353,7 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
23532353
}
23542354

23552355
Chain = DAG.getNode(RISCVISD::CALL, DL, NodeTys, Ops);
2356+
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
23562357
Glue = Chain.getValue(1);
23572358

23582359
// Mark the end of the call, which is glued to the call itself.

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4336,6 +4336,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
43364336
Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops);
43374337
}
43384338
InFlag = Chain.getValue(1);
4339+
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
43394340
DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
43404341

43414342
// Save heapallocsite metadata.

llvm/test/CodeGen/AArch64/nomerge.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; RUN: llc < %s -mtriple=aarch64 -o - | FileCheck %s
2+
3+
define void @foo(i32 %i) {
4+
entry:
5+
switch i32 %i, label %if.end3 [
6+
i32 5, label %if.then
7+
i32 7, label %if.then2
8+
]
9+
10+
if.then:
11+
tail call void @bar() #0
12+
br label %if.end3
13+
14+
if.then2:
15+
tail call void @bar() #0
16+
br label %if.end3
17+
18+
if.end3:
19+
tail call void @bar() #0
20+
ret void
21+
}
22+
23+
declare void @bar()
24+
25+
attributes #0 = { nomerge }
26+
27+
; CHECK-LABEL: foo:
28+
; CHECK: // %bb.0: // %entry
29+
; CHECK: // %bb.1: // %entry
30+
; CHECK: // %bb.2: // %if.then
31+
; CHECK-NEXT: bl bar
32+
; CHECK: b bar
33+
; CHECK: .LBB0_3: // %if.then2
34+
; CHECK-NEXT: bl bar
35+
; CHECK: .LBB0_4: // %if.end3
36+
; CHECK: b bar

llvm/test/CodeGen/ARM/nomerge.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; RUN: llc < %s -mtriple=arm -o - | FileCheck %s
2+
3+
define void @foo(i32 %i) {
4+
entry:
5+
switch i32 %i, label %if.end3 [
6+
i32 5, label %if.then
7+
i32 7, label %if.then2
8+
]
9+
10+
if.then:
11+
tail call void @bar() #0
12+
br label %if.end3
13+
14+
if.then2:
15+
tail call void @bar() #0
16+
br label %if.end3
17+
18+
if.end3:
19+
tail call void @bar() #0
20+
ret void
21+
}
22+
23+
declare void @bar()
24+
25+
attributes #0 = { nomerge }
26+
27+
; CHECK-LABEL: foo:
28+
; CHECK: @ %bb.0: @ %entry
29+
; CHECK: @ %bb.1: @ %entry
30+
; CHECK: @ %bb.2: @ %if.then
31+
; CHECK-NEXT: bl bar
32+
; CHECK: b bar
33+
; CHECK: .LBB0_3: @ %if.then2
34+
; CHECK-NEXT: bl bar
35+
; CHECK: .LBB0_4: @ %if.end3
36+
; CHECK: b bar

llvm/test/CodeGen/PowerPC/nomerge.ll

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
; RUN: llc < %s -mtriple=powerpc -o - | FileCheck %s
2+
3+
define void @foo(i32 %i) {
4+
entry:
5+
switch i32 %i, label %if.end3 [
6+
i32 5, label %if.then
7+
i32 7, label %if.then2
8+
]
9+
10+
if.then:
11+
tail call void @bar() #0
12+
br label %if.end3
13+
14+
if.then2:
15+
tail call void @bar() #0
16+
br label %if.end3
17+
18+
if.end3:
19+
tail call void @bar() #0
20+
ret void
21+
}
22+
23+
declare void @bar()
24+
25+
attributes #0 = { nomerge }
26+
27+
; CHECK-LABEL: foo:
28+
; CHECK: # %bb.0: # %entry
29+
; CHECK: # %bb.1: # %entry
30+
; CHECK: # %bb.2: # %if.then
31+
; CHECK-NEXT: bl bar
32+
; CHECK: .LBB0_3: # %if.then2
33+
; CHECK-NEXT: bl bar
34+
; CHECK: .LBB0_4: # %if.end3
35+
; CHECK-NEXT: bl bar

llvm/test/CodeGen/RISCV/nomerge.ll

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
; RUN: llc < %s -mtriple=riscv64 -o - | FileCheck %s
2+
3+
define void @foo(i32 %i) {
4+
entry:
5+
switch i32 %i, label %if.end3 [
6+
i32 5, label %if.then
7+
i32 7, label %if.then2
8+
]
9+
10+
if.then:
11+
tail call void @bar() #0
12+
br label %if.end3
13+
14+
if.then2:
15+
tail call void @bar() #0
16+
br label %if.end3
17+
18+
if.end3:
19+
tail call void @bar() #0
20+
ret void
21+
}
22+
23+
declare void @bar()
24+
25+
attributes #0 = { nomerge }
26+
27+
; CHECK-LABEL: foo:
28+
; CHECK: # %bb.0: # %entry
29+
; CHECK: # %bb.1: # %entry
30+
; CHECK: # %bb.2: # %if.then
31+
; CHECK-NEXT: call bar
32+
; CHECK: .LBB0_3: # %if.then2
33+
; CHECK-NEXT: call bar
34+
; CHECK: .LBB0_4: # %if.end3
35+
; CHECK: tail bar

llvm/test/CodeGen/X86/nomerge.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; RUN: llc < %s -mtriple=x86_64 -o - | FileCheck %s
2+
3+
define void @foo(i32 %i) {
4+
entry:
5+
switch i32 %i, label %if.end3 [
6+
i32 5, label %if.then
7+
i32 7, label %if.then2
8+
]
9+
10+
if.then:
11+
tail call void @bar() #0
12+
br label %if.end3
13+
14+
if.then2:
15+
tail call void @bar() #0
16+
br label %if.end3
17+
18+
if.end3:
19+
tail call void @bar() #0
20+
ret void
21+
}
22+
23+
declare void @bar()
24+
25+
attributes #0 = { nomerge }
26+
27+
; CHECK-LABEL: foo:
28+
; CHECK: # %bb.0: # %entry
29+
; CHECK: # %bb.1: # %entry
30+
; CHECK: # %bb.2: # %if.then
31+
; CHECK-NEXT: callq bar
32+
; CHECK: jmp bar # TAILCALL
33+
; CHECK: .LBB0_3: # %if.then2
34+
; CHECK: callq bar
35+
; CHECK: .LBB0_4: # %if.end3
36+
; CHECK: jmp bar # TAILCALL

0 commit comments

Comments
 (0)