Skip to content

Commit 88bc29f

Browse files
committed
[RISCV] Introduce a RISCV CondCode enum instead of using ISD:SET* in MIR. NFC
Previously we converted ISD condition codes to integers and stored them directly in our MIR instructions. The ISD enum kind of belongs to SelectionDAG so that seems like incorrect layering. This patch instead uses a CondCode node on RISCV::SELECT_CC until isel and then converts it from ISD encoding to a RISCV specific value. This value can be converted to/from the RISCV branch opcodes in the RISCV namespace. My larger motivation is to possibly support a microarchitectural feature of some CPUs where a short forward branch over a single instruction can be predicated internally. This will require a new pseudo instruction for select that needs to carry a branch condition and live probably until RISCVExpandPseudos. At that point it can be expanded to control flow without other instructions ending up in the predicated basic block. Using an ISD encoding in RISCVExpandPseudos doesn't seem like correct layering. Reviewed By: luismarques Differential Revision: https://reviews.llvm.org/D107400
1 parent 20dfe05 commit 88bc29f

File tree

6 files changed

+129
-60
lines changed

6 files changed

+129
-60
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,28 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
8383
void selectVSSEG(SDNode *Node, bool IsMasked, bool IsStrided);
8484
void selectVSXSEG(SDNode *Node, bool IsMasked, bool IsOrdered);
8585

86+
// Return the RISC-V condition code that matches the given DAG integer
87+
// condition code. The CondCode must be one of those supported by the RISC-V
88+
// ISA (see translateSetCCForBranch).
89+
static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) {
90+
switch (CC) {
91+
default:
92+
llvm_unreachable("Unsupported CondCode");
93+
case ISD::SETEQ:
94+
return RISCVCC::COND_EQ;
95+
case ISD::SETNE:
96+
return RISCVCC::COND_NE;
97+
case ISD::SETLT:
98+
return RISCVCC::COND_LT;
99+
case ISD::SETGE:
100+
return RISCVCC::COND_GE;
101+
case ISD::SETULT:
102+
return RISCVCC::COND_LTU;
103+
case ISD::SETUGE:
104+
return RISCVCC::COND_GEU;
105+
}
106+
}
107+
86108
// Include the pieces autogenerated from the target description.
87109
#include "RISCVGenDAGISel.inc"
88110

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,28 +1071,6 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS,
10711071
}
10721072
}
10731073

1074-
// Return the RISC-V branch opcode that matches the given DAG integer
1075-
// condition code. The CondCode must be one of those supported by the RISC-V
1076-
// ISA (see translateSetCCForBranch).
1077-
static unsigned getBranchOpcodeForIntCondCode(ISD::CondCode CC) {
1078-
switch (CC) {
1079-
default:
1080-
llvm_unreachable("Unsupported CondCode");
1081-
case ISD::SETEQ:
1082-
return RISCV::BEQ;
1083-
case ISD::SETNE:
1084-
return RISCV::BNE;
1085-
case ISD::SETLT:
1086-
return RISCV::BLT;
1087-
case ISD::SETGE:
1088-
return RISCV::BGE;
1089-
case ISD::SETULT:
1090-
return RISCV::BLTU;
1091-
case ISD::SETUGE:
1092-
return RISCV::BGEU;
1093-
}
1094-
}
1095-
10961074
RISCVII::VLMUL RISCVTargetLowering::getLMUL(MVT VT) {
10971075
assert(VT.isScalableVector() && "Expecting a scalable vector type");
10981076
unsigned KnownSize = VT.getSizeInBits().getKnownMinValue();
@@ -3002,7 +2980,7 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
30022980

30032981
translateSetCCForBranch(DL, LHS, RHS, CCVal, DAG);
30042982

3005-
SDValue TargetCC = DAG.getTargetConstant(CCVal, DL, XLenVT);
2983+
SDValue TargetCC = DAG.getCondCode(CCVal);
30062984
SDValue Ops[] = {LHS, RHS, TargetCC, TrueV, FalseV};
30072985
return DAG.getNode(RISCVISD::SELECT_CC, DL, Op.getValueType(), Ops);
30082986
}
@@ -3011,7 +2989,7 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
30112989
// (select condv, truev, falsev)
30122990
// -> (riscvisd::select_cc condv, zero, setne, truev, falsev)
30132991
SDValue Zero = DAG.getConstant(0, DL, XLenVT);
3014-
SDValue SetNE = DAG.getTargetConstant(ISD::SETNE, DL, XLenVT);
2992+
SDValue SetNE = DAG.getCondCode(ISD::SETNE);
30152993

30162994
SDValue Ops[] = {CondV, Zero, SetNE, TrueV, FalseV};
30172995

@@ -6177,7 +6155,7 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
61776155
// Transform
61786156
SDValue LHS = N->getOperand(0);
61796157
SDValue RHS = N->getOperand(1);
6180-
auto CCVal = static_cast<ISD::CondCode>(N->getConstantOperandVal(2));
6158+
ISD::CondCode CCVal = cast<CondCodeSDNode>(N->getOperand(2))->get();
61816159
if (!ISD::isIntEqualitySetCC(CCVal))
61826160
break;
61836161

@@ -6198,8 +6176,7 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
61986176
LHS = LHS.getOperand(0);
61996177
translateSetCCForBranch(DL, LHS, RHS, CCVal, DAG);
62006178

6201-
SDValue TargetCC =
6202-
DAG.getTargetConstant(CCVal, DL, Subtarget.getXLenVT());
6179+
SDValue TargetCC = DAG.getCondCode(CCVal);
62036180
return DAG.getNode(
62046181
RISCVISD::SELECT_CC, DL, N->getValueType(0),
62056182
{LHS, RHS, TargetCC, N->getOperand(3), N->getOperand(4)});
@@ -6219,8 +6196,7 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
62196196
if (isOneConstant(RHS) && DAG.MaskedValueIsZero(LHS, Mask)) {
62206197
SDLoc DL(N);
62216198
CCVal = ISD::getSetCCInverse(CCVal, LHS.getValueType());
6222-
SDValue TargetCC =
6223-
DAG.getTargetConstant(CCVal, DL, Subtarget.getXLenVT());
6199+
SDValue TargetCC = DAG.getCondCode(CCVal);
62246200
RHS = DAG.getConstant(0, DL, LHS.getValueType());
62256201
return DAG.getNode(
62266202
RISCVISD::SELECT_CC, DL, N->getValueType(0),
@@ -6881,7 +6857,8 @@ static bool isSelectPseudo(MachineInstr &MI) {
68816857
}
68826858

68836859
static MachineBasicBlock *emitSelectPseudo(MachineInstr &MI,
6884-
MachineBasicBlock *BB) {
6860+
MachineBasicBlock *BB,
6861+
const RISCVSubtarget &Subtarget) {
68856862
// To "insert" Select_* instructions, we actually have to insert the triangle
68866863
// control-flow pattern. The incoming instructions know the destination vreg
68876864
// to set, the condition code register to branch on, the true/false values to
@@ -6908,7 +6885,7 @@ static MachineBasicBlock *emitSelectPseudo(MachineInstr &MI,
69086885
// related approach and more information.
69096886
Register LHS = MI.getOperand(1).getReg();
69106887
Register RHS = MI.getOperand(2).getReg();
6911-
auto CC = static_cast<ISD::CondCode>(MI.getOperand(3).getImm());
6888+
auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
69126889

69136890
SmallVector<MachineInstr *, 4> SelectDebugValues;
69146891
SmallSet<Register, 4> SelectDests;
@@ -6941,7 +6918,7 @@ static MachineBasicBlock *emitSelectPseudo(MachineInstr &MI,
69416918
}
69426919
}
69436920

6944-
const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
6921+
const RISCVInstrInfo &TII = *Subtarget.getInstrInfo();
69456922
const BasicBlock *LLVM_BB = BB->getBasicBlock();
69466923
DebugLoc DL = MI.getDebugLoc();
69476924
MachineFunction::iterator I = ++BB->getIterator();
@@ -6970,9 +6947,7 @@ static MachineBasicBlock *emitSelectPseudo(MachineInstr &MI,
69706947
HeadMBB->addSuccessor(TailMBB);
69716948

69726949
// Insert appropriate branch.
6973-
unsigned Opcode = getBranchOpcodeForIntCondCode(CC);
6974-
6975-
BuildMI(HeadMBB, DL, TII.get(Opcode))
6950+
BuildMI(HeadMBB, DL, TII.getBrCond(CC))
69766951
.addReg(LHS)
69776952
.addReg(RHS)
69786953
.addMBB(TailMBB);
@@ -7017,7 +6992,7 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
70176992
case RISCV::Select_FPR16_Using_CC_GPR:
70186993
case RISCV::Select_FPR32_Using_CC_GPR:
70196994
case RISCV::Select_FPR64_Using_CC_GPR:
7020-
return emitSelectPseudo(MI, BB);
6995+
return emitSelectPseudo(MI, BB, Subtarget);
70216996
case RISCV::BuildPairF64Pseudo:
70226997
return emitBuildPairF64Pseudo(MI, BB);
70236998
case RISCV::SplitF64Pseudo:

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,25 @@ void RISCVInstrInfo::movImm(MachineBasicBlock &MBB,
469469
}
470470
}
471471

472+
static RISCVCC::CondCode getCondFromBranchOpc(unsigned Opc) {
473+
switch (Opc) {
474+
default:
475+
return RISCVCC::COND_INVALID;
476+
case RISCV::BEQ:
477+
return RISCVCC::COND_EQ;
478+
case RISCV::BNE:
479+
return RISCVCC::COND_NE;
480+
case RISCV::BLT:
481+
return RISCVCC::COND_LT;
482+
case RISCV::BGE:
483+
return RISCVCC::COND_GE;
484+
case RISCV::BLTU:
485+
return RISCVCC::COND_LTU;
486+
case RISCV::BGEU:
487+
return RISCVCC::COND_GEU;
488+
}
489+
}
490+
472491
// The contents of values added to Cond are not examined outside of
473492
// RISCVInstrInfo, giving us flexibility in what to push to it. For RISCV, we
474493
// push BranchOpcode, Reg1, Reg2.
@@ -478,27 +497,47 @@ static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target,
478497
assert(LastInst.getDesc().isConditionalBranch() &&
479498
"Unknown conditional branch");
480499
Target = LastInst.getOperand(2).getMBB();
481-
Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode()));
500+
unsigned CC = getCondFromBranchOpc(LastInst.getOpcode());
501+
Cond.push_back(MachineOperand::CreateImm(CC));
482502
Cond.push_back(LastInst.getOperand(0));
483503
Cond.push_back(LastInst.getOperand(1));
484504
}
485505

486-
static unsigned getOppositeBranchOpcode(int Opc) {
487-
switch (Opc) {
506+
const MCInstrDesc &RISCVInstrInfo::getBrCond(RISCVCC::CondCode CC) const {
507+
switch (CC) {
508+
default:
509+
llvm_unreachable("Unknown condition code!");
510+
case RISCVCC::COND_EQ:
511+
return get(RISCV::BEQ);
512+
case RISCVCC::COND_NE:
513+
return get(RISCV::BNE);
514+
case RISCVCC::COND_LT:
515+
return get(RISCV::BLT);
516+
case RISCVCC::COND_GE:
517+
return get(RISCV::BGE);
518+
case RISCVCC::COND_LTU:
519+
return get(RISCV::BLTU);
520+
case RISCVCC::COND_GEU:
521+
return get(RISCV::BGEU);
522+
}
523+
}
524+
525+
RISCVCC::CondCode RISCVCC::getOppositeBranchCondition(RISCVCC::CondCode CC) {
526+
switch (CC) {
488527
default:
489528
llvm_unreachable("Unrecognized conditional branch");
490-
case RISCV::BEQ:
491-
return RISCV::BNE;
492-
case RISCV::BNE:
493-
return RISCV::BEQ;
494-
case RISCV::BLT:
495-
return RISCV::BGE;
496-
case RISCV::BGE:
497-
return RISCV::BLT;
498-
case RISCV::BLTU:
499-
return RISCV::BGEU;
500-
case RISCV::BGEU:
501-
return RISCV::BLTU;
529+
case RISCVCC::COND_EQ:
530+
return RISCVCC::COND_NE;
531+
case RISCVCC::COND_NE:
532+
return RISCVCC::COND_EQ;
533+
case RISCVCC::COND_LT:
534+
return RISCVCC::COND_GE;
535+
case RISCVCC::COND_GE:
536+
return RISCVCC::COND_LT;
537+
case RISCVCC::COND_LTU:
538+
return RISCVCC::COND_GEU;
539+
case RISCVCC::COND_GEU:
540+
return RISCVCC::COND_LTU;
502541
}
503542
}
504543

@@ -624,9 +663,9 @@ unsigned RISCVInstrInfo::insertBranch(
624663
}
625664

626665
// Either a one or two-way conditional branch.
627-
unsigned Opc = Cond[0].getImm();
666+
auto CC = static_cast<RISCVCC::CondCode>(Cond[0].getImm());
628667
MachineInstr &CondMI =
629-
*BuildMI(&MBB, DL, get(Opc)).add(Cond[1]).add(Cond[2]).addMBB(TBB);
668+
*BuildMI(&MBB, DL, getBrCond(CC)).add(Cond[1]).add(Cond[2]).addMBB(TBB);
630669
if (BytesAdded)
631670
*BytesAdded += getInstSizeInBytes(CondMI);
632671

@@ -680,7 +719,8 @@ unsigned RISCVInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
680719
bool RISCVInstrInfo::reverseBranchCondition(
681720
SmallVectorImpl<MachineOperand> &Cond) const {
682721
assert((Cond.size() == 3) && "Invalid branch condition!");
683-
Cond[0].setImm(getOppositeBranchOpcode(Cond[0].getImm()));
722+
auto CC = static_cast<RISCVCC::CondCode>(Cond[0].getImm());
723+
Cond[0].setImm(getOppositeBranchCondition(CC));
684724
return false;
685725
}
686726

llvm/lib/Target/RISCV/RISCVInstrInfo.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,29 @@ namespace llvm {
2424

2525
class RISCVSubtarget;
2626

27+
namespace RISCVCC {
28+
29+
enum CondCode {
30+
COND_EQ,
31+
COND_NE,
32+
COND_LT,
33+
COND_GE,
34+
COND_LTU,
35+
COND_GEU,
36+
COND_INVALID
37+
};
38+
39+
CondCode getOppositeBranchCondition(CondCode);
40+
41+
} // end of namespace RISCVCC
42+
2743
class RISCVInstrInfo : public RISCVGenInstrInfo {
2844

2945
public:
3046
explicit RISCVInstrInfo(RISCVSubtarget &STI);
3147

3248
MCInst getNop() const override;
49+
const MCInstrDesc &getBrCond(RISCVCC::CondCode CC) const;
3350

3451
unsigned isLoadFromStackSlot(const MachineInstr &MI,
3552
int &FrameIndex) const override;

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>,
2323
// Target-dependent type requirements.
2424
def SDT_RISCVCall : SDTypeProfile<0, -1, [SDTCisVT<0, XLenVT>]>;
2525
def SDT_RISCVSelectCC : SDTypeProfile<1, 5, [SDTCisSameAs<1, 2>,
26+
SDTCisVT<3, OtherVT>,
2627
SDTCisSameAs<0, 4>,
2728
SDTCisSameAs<4, 5>]>;
2829
def SDT_RISCVBrCC : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,
@@ -974,13 +975,27 @@ def : Pat<(setgt GPR:$rs1, GPR:$rs2), (SLT GPR:$rs2, GPR:$rs1)>;
974975
def : Pat<(setge GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs1, GPR:$rs2), 1)>;
975976
def : Pat<(setle GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs2, GPR:$rs1), 1)>;
976977

978+
def IntCCtoRISCVCC : SDNodeXForm<riscv_selectcc, [{
979+
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
980+
RISCVCC::CondCode BrCC = getRISCVCCForIntCC(CC);
981+
return CurDAG->getTargetConstant(BrCC, SDLoc(N), Subtarget->getXLenVT());
982+
}]>;
983+
984+
def riscv_selectcc_frag : PatFrag<(ops node:$lhs, node:$rhs, node:$cc,
985+
node:$truev, node:$falsev),
986+
(riscv_selectcc node:$lhs, node:$rhs,
987+
node:$cc, node:$truev,
988+
node:$falsev), [{}],
989+
IntCCtoRISCVCC>;
990+
977991
let usesCustomInserter = 1 in
978992
class SelectCC_rrirr<RegisterClass valty, RegisterClass cmpty>
979993
: Pseudo<(outs valty:$dst),
980994
(ins cmpty:$lhs, cmpty:$rhs, ixlenimm:$imm,
981995
valty:$truev, valty:$falsev),
982-
[(set valty:$dst, (riscv_selectcc cmpty:$lhs, cmpty:$rhs,
983-
(XLenVT timm:$imm), valty:$truev, valty:$falsev))]>;
996+
[(set valty:$dst,
997+
(riscv_selectcc_frag:$imm cmpty:$lhs, cmpty:$rhs, cond,
998+
valty:$truev, valty:$falsev))]>;
984999

9851000
def Select_GPR_Using_CC_GPR : SelectCC_rrirr<GPR, GPR>;
9861001

llvm/test/CodeGen/RISCV/select-optimize-multiple.mir

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ body: |
140140
%0:gpr = COPY $x10
141141
%5:gpr = ANDI %0, 1
142142
%6:gpr = COPY $x0
143-
%7:gpr = Select_GPR_Using_CC_GPR %5, %6, 22, %1, %2
143+
%7:gpr = Select_GPR_Using_CC_GPR %5, %6, 1, %1, %2
144144
%8:gpr = ADDI %7, 1
145-
%9:gpr = Select_GPR_Using_CC_GPR %5, %6, 22, %3, %2
145+
%9:gpr = Select_GPR_Using_CC_GPR %5, %6, 1, %3, %2
146146
%10:gpr = ADD %7, killed %9
147147
$x10 = COPY %10
148148
PseudoRET implicit $x10
@@ -266,11 +266,11 @@ body: |
266266
%0:gpr = COPY $x10
267267
%5:gpr = ANDI %0, 1
268268
%6:gpr = COPY $x0
269-
%7:gpr = Select_GPR_Using_CC_GPR %5, %6, 22, %1, %2
269+
%7:gpr = Select_GPR_Using_CC_GPR %5, %6, 1, %1, %2
270270
DBG_VALUE %7, $noreg
271271
%8:gpr = ADDI %0, 1
272272
DBG_VALUE %8, $noreg
273-
%9:gpr = Select_GPR_Using_CC_GPR %5, %6, 22, %3, %2
273+
%9:gpr = Select_GPR_Using_CC_GPR %5, %6, 1, %3, %2
274274
DBG_VALUE %9, $noreg
275275
%10:gpr = ADD %7, killed %9
276276
$x10 = COPY %10

0 commit comments

Comments
 (0)