Skip to content

Commit 7f87b5b

Browse files
authored
[SelectionDAG][X86] Preserve unpredictable metadata for conditional branches in SelectionDAG, as well as JCCs generated by X86 backend. (#102101)
This builds on 09515f2, which preserves unpredictable metadata in CodeGen for `select`. This patch does it for conditional branches.
1 parent 4eefc8d commit 7f87b5b

File tree

8 files changed

+72
-39
lines changed

8 files changed

+72
-39
lines changed

llvm/include/llvm/CodeGen/SelectionDAG.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,8 +1163,13 @@ class SelectionDAG {
11631163
SDValue N2, SDValue N3, const SDNodeFlags Flags);
11641164
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
11651165
SDValue N2, SDValue N3, SDValue N4);
1166+
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
1167+
SDValue N2, SDValue N3, SDValue N4, const SDNodeFlags Flags);
11661168
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
11671169
SDValue N2, SDValue N3, SDValue N4, SDValue N5);
1170+
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
1171+
SDValue N2, SDValue N3, SDValue N4, SDValue N5,
1172+
const SDNodeFlags Flags);
11681173

11691174
// Specialize again based on number of operands for nodes with a VTList
11701175
// rather than a single VT.

llvm/include/llvm/CodeGen/SwitchLoweringUtils.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,29 +137,34 @@ struct CaseBlock {
137137
SDLoc DL;
138138
DebugLoc DbgLoc;
139139

140-
// Branch weights.
140+
// Branch weights and predictability.
141141
BranchProbability TrueProb, FalseProb;
142+
bool IsUnpredictable;
142143

143144
// Constructor for SelectionDAG.
144145
CaseBlock(ISD::CondCode cc, const Value *cmplhs, const Value *cmprhs,
145146
const Value *cmpmiddle, MachineBasicBlock *truebb,
146147
MachineBasicBlock *falsebb, MachineBasicBlock *me, SDLoc dl,
147148
BranchProbability trueprob = BranchProbability::getUnknown(),
148-
BranchProbability falseprob = BranchProbability::getUnknown())
149+
BranchProbability falseprob = BranchProbability::getUnknown(),
150+
bool isunpredictable = false)
149151
: CC(cc), CmpLHS(cmplhs), CmpMHS(cmpmiddle), CmpRHS(cmprhs),
150152
TrueBB(truebb), FalseBB(falsebb), ThisBB(me), DL(dl),
151-
TrueProb(trueprob), FalseProb(falseprob) {}
153+
TrueProb(trueprob), FalseProb(falseprob),
154+
IsUnpredictable(isunpredictable) {}
152155

153156
// Constructor for GISel.
154157
CaseBlock(CmpInst::Predicate pred, bool nocmp, const Value *cmplhs,
155158
const Value *cmprhs, const Value *cmpmiddle,
156159
MachineBasicBlock *truebb, MachineBasicBlock *falsebb,
157160
MachineBasicBlock *me, DebugLoc dl,
158161
BranchProbability trueprob = BranchProbability::getUnknown(),
159-
BranchProbability falseprob = BranchProbability::getUnknown())
162+
BranchProbability falseprob = BranchProbability::getUnknown(),
163+
bool isunpredictable = false)
160164
: PredInfo({pred, nocmp}), CmpLHS(cmplhs), CmpMHS(cmpmiddle),
161165
CmpRHS(cmprhs), TrueBB(truebb), FalseBB(falsebb), ThisBB(me),
162-
DbgLoc(dl), TrueProb(trueprob), FalseProb(falseprob) {}
166+
DbgLoc(dl), TrueProb(trueprob), FalseProb(falseprob),
167+
IsUnpredictable(isunpredictable) {}
163168
};
164169

165170
struct JumpTable {

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18299,7 +18299,7 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
1829918299
// nondeterministic jumps).
1830018300
if (N1->getOpcode() == ISD::FREEZE && N1.hasOneUse()) {
1830118301
return DAG.getNode(ISD::BRCOND, SDLoc(N), MVT::Other, Chain,
18302-
N1->getOperand(0), N2);
18302+
N1->getOperand(0), N2, N->getFlags());
1830318303
}
1830418304

1830518305
// Variant of the previous fold where there is a SETCC in between:
@@ -18348,7 +18348,8 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
1834818348
if (Updated)
1834918349
return DAG.getNode(
1835018350
ISD::BRCOND, SDLoc(N), MVT::Other, Chain,
18351-
DAG.getSetCC(SDLoc(N1), N1->getValueType(0), S0, S1, Cond), N2);
18351+
DAG.getSetCC(SDLoc(N1), N1->getValueType(0), S0, S1, Cond), N2,
18352+
N->getFlags());
1835218353
}
1835318354

1835418355
// If N is a constant we could fold this into a fallthrough or unconditional
@@ -18373,7 +18374,7 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
1837318374
HandleSDNode ChainHandle(Chain);
1837418375
if (SDValue NewN1 = rebuildSetCC(N1))
1837518376
return DAG.getNode(ISD::BRCOND, SDLoc(N), MVT::Other,
18376-
ChainHandle.getValue(), NewN1, N2);
18377+
ChainHandle.getValue(), NewN1, N2, N->getFlags());
1837718378
}
1837818379

1837918380
return SDValue();

llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,14 +1065,17 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
10651065
// Create the new machine instruction.
10661066
MachineInstrBuilder MIB = BuildMI(*MF, Node->getDebugLoc(), II);
10671067

1068+
// Transfer IR flags from the SDNode to the MachineInstr
1069+
MachineInstr *MI = MIB.getInstr();
1070+
const SDNodeFlags Flags = Node->getFlags();
1071+
if (Flags.hasUnpredictable())
1072+
MI->setFlag(MachineInstr::MIFlag::Unpredictable);
1073+
10681074
// Add result register values for things that are defined by this
10691075
// instruction.
10701076
if (NumResults) {
10711077
CreateVirtualRegisters(Node, MIB, II, IsClone, IsCloned, VRBaseMap);
10721078

1073-
// Transfer any IR flags from the SDNode to the MachineInstr
1074-
MachineInstr *MI = MIB.getInstr();
1075-
const SDNodeFlags Flags = Node->getFlags();
10761079
if (Flags.hasNoSignedZeros())
10771080
MI->setFlag(MachineInstr::MIFlag::FmNsz);
10781081

@@ -1105,9 +1108,6 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
11051108

11061109
if (Flags.hasNoFPExcept())
11071110
MI->setFlag(MachineInstr::MIFlag::NoFPExcept);
1108-
1109-
if (Flags.hasUnpredictable())
1110-
MI->setFlag(MachineInstr::MIFlag::Unpredictable);
11111111
}
11121112

11131113
// Emit all of the actual operands of this instruction, adding them to the

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7626,16 +7626,34 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
76267626
}
76277627

76287628
SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
7629-
SDValue N1, SDValue N2, SDValue N3, SDValue N4) {
7629+
SDValue N1, SDValue N2, SDValue N3, SDValue N4,
7630+
const SDNodeFlags Flags) {
76307631
SDValue Ops[] = { N1, N2, N3, N4 };
7631-
return getNode(Opcode, DL, VT, Ops);
7632+
return getNode(Opcode, DL, VT, Ops, Flags);
7633+
}
7634+
7635+
SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
7636+
SDValue N1, SDValue N2, SDValue N3, SDValue N4) {
7637+
SDNodeFlags Flags;
7638+
if (Inserter)
7639+
Flags = Inserter->getFlags();
7640+
return getNode(Opcode, DL, VT, N1, N2, N3, N4, Flags);
76327641
}
76337642

76347643
SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
76357644
SDValue N1, SDValue N2, SDValue N3, SDValue N4,
7636-
SDValue N5) {
7645+
SDValue N5, const SDNodeFlags Flags) {
76377646
SDValue Ops[] = { N1, N2, N3, N4, N5 };
7638-
return getNode(Opcode, DL, VT, Ops);
7647+
return getNode(Opcode, DL, VT, Ops, Flags);
7648+
}
7649+
7650+
SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
7651+
SDValue N1, SDValue N2, SDValue N3, SDValue N4,
7652+
SDValue N5) {
7653+
SDNodeFlags Flags;
7654+
if (Inserter)
7655+
Flags = Inserter->getFlags();
7656+
return getNode(Opcode, DL, VT, N1, N2, N3, N4, N5, Flags);
76397657
}
76407658

76417659
/// getStackArgumentTokenFactor - Compute a TokenFactor to force all

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2818,9 +2818,10 @@ void SelectionDAGBuilder::visitBr(const BranchInst &I) {
28182818
// je foo
28192819
// cmp D, E
28202820
// jle foo
2821+
bool IsUnpredictable = I.hasMetadata(LLVMContext::MD_unpredictable);
28212822
const Instruction *BOp = dyn_cast<Instruction>(CondVal);
28222823
if (!DAG.getTargetLoweringInfo().isJumpExpensive() && BOp &&
2823-
BOp->hasOneUse() && !I.hasMetadata(LLVMContext::MD_unpredictable)) {
2824+
BOp->hasOneUse() && !IsUnpredictable) {
28242825
Value *Vec;
28252826
const Value *BOp0, *BOp1;
28262827
Instruction::BinaryOps Opcode = (Instruction::BinaryOps)0;
@@ -2869,7 +2870,9 @@ void SelectionDAGBuilder::visitBr(const BranchInst &I) {
28692870

28702871
// Create a CaseBlock record representing this branch.
28712872
CaseBlock CB(ISD::SETEQ, CondVal, ConstantInt::getTrue(*DAG.getContext()),
2872-
nullptr, Succ0MBB, Succ1MBB, BrMBB, getCurSDLoc());
2873+
nullptr, Succ0MBB, Succ1MBB, BrMBB, getCurSDLoc(),
2874+
BranchProbability::getUnknown(), BranchProbability::getUnknown(),
2875+
IsUnpredictable);
28732876

28742877
// Use visitSwitchCase to actually insert the fast branch sequence for this
28752878
// cond branch.
@@ -2957,9 +2960,10 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB,
29572960
Cond = DAG.getNode(ISD::XOR, dl, Cond.getValueType(), Cond, True);
29582961
}
29592962

2960-
SDValue BrCond = DAG.getNode(ISD::BRCOND, dl,
2961-
MVT::Other, getControlRoot(), Cond,
2962-
DAG.getBasicBlock(CB.TrueBB));
2963+
SDNodeFlags Flags;
2964+
Flags.setUnpredictable(CB.IsUnpredictable);
2965+
SDValue BrCond = DAG.getNode(ISD::BRCOND, dl, MVT::Other, getControlRoot(),
2966+
Cond, DAG.getBasicBlock(CB.TrueBB), Flags);
29632967

29642968
setValue(CurInst, BrCond);
29652969

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24833,14 +24833,14 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
2483324833

2483424834
SDValue CCVal = DAG.getTargetConstant(X86Cond, dl, MVT::i8);
2483524835
return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
24836-
Overflow);
24836+
Overflow, Op->getFlags());
2483724837
}
2483824838

2483924839
if (LHS.getSimpleValueType().isInteger()) {
2484024840
SDValue CCVal;
2484124841
SDValue EFLAGS = emitFlagsForSetcc(LHS, RHS, CC, SDLoc(Cond), DAG, CCVal);
2484224842
return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
24843-
EFLAGS);
24843+
EFLAGS, Op->getFlags());
2484424844
}
2484524845

2484624846
if (CC == ISD::SETOEQ) {
@@ -24866,10 +24866,10 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
2486624866
DAG.getNode(X86ISD::FCMP, SDLoc(Cond), MVT::i32, LHS, RHS);
2486724867
SDValue CCVal = DAG.getTargetConstant(X86::COND_NE, dl, MVT::i8);
2486824868
Chain = DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest,
24869-
CCVal, Cmp);
24869+
CCVal, Cmp, Op->getFlags());
2487024870
CCVal = DAG.getTargetConstant(X86::COND_P, dl, MVT::i8);
2487124871
return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
24872-
Cmp);
24872+
Cmp, Op->getFlags());
2487324873
}
2487424874
}
2487524875
} else if (CC == ISD::SETUNE) {
@@ -24878,18 +24878,18 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
2487824878
// separate test.
2487924879
SDValue Cmp = DAG.getNode(X86ISD::FCMP, SDLoc(Cond), MVT::i32, LHS, RHS);
2488024880
SDValue CCVal = DAG.getTargetConstant(X86::COND_NE, dl, MVT::i8);
24881-
Chain =
24882-
DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal, Cmp);
24881+
Chain = DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
24882+
Cmp, Op->getFlags());
2488324883
CCVal = DAG.getTargetConstant(X86::COND_P, dl, MVT::i8);
2488424884
return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
24885-
Cmp);
24885+
Cmp, Op->getFlags());
2488624886
} else {
2488724887
X86::CondCode X86Cond =
2488824888
TranslateX86CC(CC, dl, /*IsFP*/ true, LHS, RHS, DAG);
2488924889
SDValue Cmp = DAG.getNode(X86ISD::FCMP, SDLoc(Cond), MVT::i32, LHS, RHS);
2489024890
SDValue CCVal = DAG.getTargetConstant(X86Cond, dl, MVT::i8);
2489124891
return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
24892-
Cmp);
24892+
Cmp, Op->getFlags());
2489324893
}
2489424894
}
2489524895

@@ -24900,7 +24900,7 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
2490024900

2490124901
SDValue CCVal = DAG.getTargetConstant(X86Cond, dl, MVT::i8);
2490224902
return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
24903-
Overflow);
24903+
Overflow, Op->getFlags());
2490424904
}
2490524905

2490624906
// Look past the truncate if the high bits are known zero.
@@ -24919,8 +24919,8 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
2491924919

2492024920
SDValue CCVal;
2492124921
SDValue EFLAGS = emitFlagsForSetcc(LHS, RHS, ISD::SETNE, dl, DAG, CCVal);
24922-
return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
24923-
EFLAGS);
24922+
return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal, EFLAGS,
24923+
Op->getFlags());
2492424924
}
2492524925

2492624926
// Lower dynamic stack allocation to _alloca call for Cygwin/Mingw targets.

llvm/test/CodeGen/X86/unpredictable-brcond.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2-
; Currently, unpredictable metadata on conditional branches is lost during CodeGen.
2+
; Make sure MIR generated for conditional branch with unpredictable metadata has unpredictable flag.
33
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -stop-after=finalize-isel < %s | FileCheck %s
44

55
define void @cond_branch_1(i1 %cond) {
@@ -11,7 +11,7 @@ define void @cond_branch_1(i1 %cond) {
1111
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edi
1212
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
1313
; CHECK-NEXT: TEST8ri killed [[COPY1]], 1, implicit-def $eflags
14-
; CHECK-NEXT: JCC_1 %bb.2, 4, implicit $eflags
14+
; CHECK-NEXT: unpredictable JCC_1 %bb.2, 4, implicit $eflags
1515
; CHECK-NEXT: JMP_1 %bb.1
1616
; CHECK-NEXT: {{ $}}
1717
; CHECK-NEXT: bb.1.then:
@@ -51,7 +51,7 @@ define void @cond_branch_2(double %a, double %b, i32 %c, i32 %d) nounwind {
5151
; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 6, implicit $eflags
5252
; CHECK-NEXT: [[OR8rr:%[0-9]+]]:gr8 = OR8rr [[SETCCr]], killed [[SETCCr1]], implicit-def dead $eflags
5353
; CHECK-NEXT: TEST8rr [[OR8rr]], [[OR8rr]], implicit-def $eflags
54-
; CHECK-NEXT: JCC_1 %bb.2, 5, implicit $eflags
54+
; CHECK-NEXT: unpredictable JCC_1 %bb.2, 5, implicit $eflags
5555
; CHECK-NEXT: JMP_1 %bb.1
5656
; CHECK-NEXT: {{ $}}
5757
; CHECK-NEXT: bb.1.true:
@@ -89,8 +89,8 @@ define void @isint_branch(double %d) nounwind {
8989
; CHECK-NEXT: [[CVTDQ2PDrr:%[0-9]+]]:vr128 = CVTDQ2PDrr killed [[CVTTPD2DQrr]]
9090
; CHECK-NEXT: [[COPY2:%[0-9]+]]:fr64 = COPY [[CVTDQ2PDrr]]
9191
; CHECK-NEXT: nofpexcept UCOMISDrr [[COPY]], killed [[COPY2]], implicit-def $eflags, implicit $mxcsr
92-
; CHECK-NEXT: JCC_1 %bb.2, 5, implicit $eflags
93-
; CHECK-NEXT: JCC_1 %bb.2, 10, implicit $eflags
92+
; CHECK-NEXT: unpredictable JCC_1 %bb.2, 5, implicit $eflags
93+
; CHECK-NEXT: unpredictable JCC_1 %bb.2, 10, implicit $eflags
9494
; CHECK-NEXT: JMP_1 %bb.1
9595
; CHECK-NEXT: {{ $}}
9696
; CHECK-NEXT: bb.1.true:

0 commit comments

Comments
 (0)