Skip to content

Commit 8838a24

Browse files
committed
[RISCV] Add isel patterns for generating XAndesPerf branch immediate instructions
Similar to llvm#139872. This patch adds isel patterns to match `riscv_brcc` and `riscv_selectcc_frag` to XAndesPerf branch instructions.
1 parent c67353e commit 8838a24

File tree

6 files changed

+120
-24
lines changed

6 files changed

+120
-24
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2416,11 +2416,16 @@ unsigned RISCVTargetLowering::getVectorTypeBreakdownForCallingConv(
24162416
// with 1/-1.
24172417
static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS,
24182418
ISD::CondCode &CC, SelectionDAG &DAG) {
2419+
const RISCVSubtarget &Subtarget =
2420+
DAG.getMachineFunction().getSubtarget<RISCVSubtarget>();
2421+
24192422
// If this is a single bit test that can't be handled by ANDI, shift the
24202423
// bit to be tested to the MSB and perform a signed compare with 0.
24212424
if (isIntEqualitySetCC(CC) && isNullConstant(RHS) &&
24222425
LHS.getOpcode() == ISD::AND && LHS.hasOneUse() &&
2423-
isa<ConstantSDNode>(LHS.getOperand(1))) {
2426+
isa<ConstantSDNode>(LHS.getOperand(1)) &&
2427+
// XAndesPerf supports branch on test bit.
2428+
!Subtarget.hasVendorXAndesPerf()) {
24242429
uint64_t Mask = LHS.getConstantOperandVal(1);
24252430
if ((isPowerOf2_64(Mask) || isMask_64(Mask)) && !isInt<12>(Mask)) {
24262431
unsigned ShAmt = 0;
@@ -2441,8 +2446,6 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS,
24412446

24422447
if (auto *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
24432448
int64_t C = RHSC->getSExtValue();
2444-
const RISCVSubtarget &Subtarget =
2445-
DAG.getMachineFunction().getSubtarget<RISCVSubtarget>();
24462449
switch (CC) {
24472450
default: break;
24482451
case ISD::SETGT:
@@ -18262,6 +18265,14 @@ static bool combine_CC(SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL,
1826218265
uint64_t Mask = LHS0.getConstantOperandVal(1);
1826318266
uint64_t ShAmt = LHS.getConstantOperandVal(1);
1826418267
if (isPowerOf2_64(Mask) && Log2_64(Mask) == ShAmt) {
18268+
// XAndesPerf supports branch on test bit.
18269+
if (Subtarget.hasVendorXAndesPerf()) {
18270+
LHS =
18271+
DAG.getNode(ISD::AND, DL, LHS.getValueType(), LHS0.getOperand(0),
18272+
DAG.getConstant(Mask, DL, LHS.getValueType()));
18273+
return true;
18274+
}
18275+
1826518276
CCVal = CCVal == ISD::SETEQ ? ISD::SETGE : ISD::SETLT;
1826618277
CC = DAG.getCondCode(CCVal);
1826718278

@@ -21788,6 +21799,8 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
2178821799
case RISCV::Select_GPRNoX0_Using_CC_UImm5NonZero_QC:
2178921800
case RISCV::Select_GPRNoX0_Using_CC_SImm16NonZero_QC:
2179021801
case RISCV::Select_GPRNoX0_Using_CC_UImm16NonZero_QC:
21802+
case RISCV::Select_GPR_Using_CC_UImmLog2XLen_NDS:
21803+
case RISCV::Select_GPR_Using_CC_UImm7_NDS:
2179121804
case RISCV::Select_FPR16_Using_CC_GPR:
2179221805
case RISCV::Select_FPR16INX_Using_CC_GPR:
2179321806
case RISCV::Select_FPR32_Using_CC_GPR:

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,11 +966,15 @@ RISCVCC::CondCode RISCVInstrInfo::getCondFromBranchOpc(unsigned Opc) {
966966
case RISCV::CV_BEQIMM:
967967
case RISCV::QC_BEQI:
968968
case RISCV::QC_E_BEQI:
969+
case RISCV::NDS_BBC:
970+
case RISCV::NDS_BEQC:
969971
return RISCVCC::COND_EQ;
970972
case RISCV::BNE:
971973
case RISCV::QC_BNEI:
972974
case RISCV::QC_E_BNEI:
973975
case RISCV::CV_BNEIMM:
976+
case RISCV::NDS_BBS:
977+
case RISCV::NDS_BNEC:
974978
return RISCVCC::COND_NE;
975979
case RISCV::BLT:
976980
case RISCV::QC_BLTI:
@@ -1103,6 +1107,26 @@ unsigned RISCVCC::getBrCond(RISCVCC::CondCode CC, unsigned SelectOpc) {
11031107
return RISCV::QC_E_BGEUI;
11041108
}
11051109
break;
1110+
case RISCV::Select_GPR_Using_CC_UImmLog2XLen_NDS:
1111+
switch (CC) {
1112+
default:
1113+
llvm_unreachable("Unexpected condition code!");
1114+
case RISCVCC::COND_EQ:
1115+
return RISCV::NDS_BBC;
1116+
case RISCVCC::COND_NE:
1117+
return RISCV::NDS_BBS;
1118+
}
1119+
break;
1120+
case RISCV::Select_GPR_Using_CC_UImm7_NDS:
1121+
switch (CC) {
1122+
default:
1123+
llvm_unreachable("Unexpected condition code!");
1124+
case RISCVCC::COND_EQ:
1125+
return RISCV::NDS_BEQC;
1126+
case RISCVCC::COND_NE:
1127+
return RISCV::NDS_BNEC;
1128+
}
1129+
break;
11061130
}
11071131
}
11081132

@@ -1400,6 +1424,12 @@ bool RISCVInstrInfo::reverseBranchCondition(
14001424
case RISCV::QC_E_BLTUI:
14011425
Cond[0].setImm(RISCV::QC_E_BGEUI);
14021426
break;
1427+
case RISCV::NDS_BBC:
1428+
Cond[0].setImm(RISCV::NDS_BBS);
1429+
break;
1430+
case RISCV::NDS_BBS:
1431+
Cond[0].setImm(RISCV::NDS_BBC);
1432+
break;
14031433
}
14041434

14051435
return false;
@@ -1572,6 +1602,11 @@ bool RISCVInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
15721602
switch (BranchOp) {
15731603
default:
15741604
llvm_unreachable("Unexpected opcode!");
1605+
case RISCV::NDS_BBC:
1606+
case RISCV::NDS_BBS:
1607+
case RISCV::NDS_BEQC:
1608+
case RISCV::NDS_BNEC:
1609+
return isIntN(11, BrOffset);
15751610
case RISCV::BEQ:
15761611
case RISCV::BNE:
15771612
case RISCV::BLT:

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ def uimm6 : RISCVUImmLeafOp<6>;
321321
def uimm7_opcode : RISCVUImmOp<7> {
322322
let ParserMatchClass = InsnDirectiveOpcode;
323323
}
324-
def uimm7 : RISCVUImmOp<7>;
324+
def uimm7 : RISCVUImmLeafOp<7>;
325325
def uimm8 : RISCVUImmOp<8>;
326326
def uimm16 : RISCVUImmOp<16>;
327327
def uimm32 : RISCVUImmOp<32>;

llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,26 @@ def simm20_lsb000 : Operand<XLenVT> {
5353
let DecoderMethod = "decodeSImmOperandAndLslN<20, 3>";
5454
}
5555

56+
// Predicate: True if immediate is a power of 2.
57+
def PowerOf2 : PatLeaf<(imm), [{
58+
if (N->getValueType(0) == MVT::i32)
59+
return isPowerOf2_32(N->getZExtValue());
60+
else if (N->getValueType(0) == MVT::i64)
61+
return isPowerOf2_64(N->getZExtValue());
62+
else
63+
return false;
64+
}]>;
65+
66+
// Transformation function: Get log2 of immediate.
67+
def Log2 : SDNodeXForm<imm, [{
68+
uint64_t Imm;
69+
if (N->getValueType(0) == MVT::i32)
70+
Imm = Log2_32(N->getZExtValue());
71+
else
72+
Imm = Log2_64(N->getZExtValue());
73+
return CurDAG->getTargetConstant(Imm, SDLoc(N), N->getValueType(0));
74+
}]>;
75+
5676
//===----------------------------------------------------------------------===//
5777
// Instruction Class Templates
5878
//===----------------------------------------------------------------------===//
@@ -556,8 +576,44 @@ def NDS_VD4DOTSU_VV : NDSRVInstVD4DOT<0b000101, "nds.vd4dotsu">;
556576
// Pseudo-instructions and codegen patterns
557577
//===----------------------------------------------------------------------===//
558578

579+
class NDS_BBPat<CondCode Cond, NDSRVInstBB Inst>
580+
: Pat<(riscv_brcc(and(XLenVT GPR:$rs1), PowerOf2:$mask), 0, Cond,
581+
bb:$imm10),
582+
(Inst GPR:$rs1, (Log2 PowerOf2:$mask), bare_simm11_lsb0:$imm10)>;
583+
584+
class NDS_BCPat<CondCode Cond, NDSRVInstBC Inst>
585+
: Pat<(riscv_brcc(XLenVT GPR:$rs1), uimm7:$cimm, Cond, bb:$imm10),
586+
(Inst GPR:$rs1, uimm7:$cimm, bare_simm11_lsb0:$imm10)>;
587+
588+
defm CC_UImmLog2XLen_NDS : SelectCC_GPR_riirr<GPR, uimmlog2xlen>;
589+
defm CC_UImm7_NDS : SelectCC_GPR_riirr<GPR, uimm7>;
590+
591+
class SelectNDS_BB<CondCode Cond>
592+
: Pat<(riscv_selectcc_frag:$cc(and(XLenVT GPR:$lhs), PowerOf2:$mask), 0,
593+
Cond, (XLenVT GPR:$truev), GPR:$falsev),
594+
(Select_GPR_Using_CC_UImmLog2XLen_NDS GPR:$lhs, (Log2 PowerOf2:$mask),
595+
(IntCCtoRISCVCC $cc), GPR:$truev, GPR:$falsev)>;
596+
597+
class SelectNDS_BC<CondCode Cond>
598+
: Pat<(riscv_selectcc_frag:$cc(XLenVT GPR:$lhs), uimm7:$cimm, Cond,
599+
(XLenVT GPR:$truev), GPR:$falsev),
600+
(Select_GPR_Using_CC_UImm7_NDS GPR:$lhs, uimm7:$cimm,
601+
(IntCCtoRISCVCC $cc), GPR:$truev, GPR:$falsev)>;
602+
559603
let Predicates = [HasVendorXAndesPerf] in {
560604

605+
def : NDS_BBPat<SETEQ, NDS_BBC>;
606+
def : NDS_BBPat<SETNE, NDS_BBS>;
607+
608+
def : SelectNDS_BB<SETEQ>;
609+
def : SelectNDS_BB<SETNE>;
610+
611+
def : NDS_BCPat<SETEQ, NDS_BEQC>;
612+
def : NDS_BCPat<SETNE, NDS_BNEC>;
613+
614+
def : SelectNDS_BC<SETEQ>;
615+
def : SelectNDS_BC<SETNE>;
616+
561617
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (NDS_BFOS GPR:$rs1, 15, 0)>;
562618
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (NDS_BFOS GPR:$rs1, 7, 0)>;
563619
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i1), (NDS_BFOS GPR:$rs1, 0, 0)>;

llvm/lib/Target/RISCV/RISCVInstrPredicates.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ def isSelectPseudo
5454
Select_GPRNoX0_Using_CC_UImm5NonZero_QC,
5555
Select_GPRNoX0_Using_CC_SImm16NonZero_QC,
5656
Select_GPRNoX0_Using_CC_UImm16NonZero_QC,
57+
Select_GPR_Using_CC_UImmLog2XLen_NDS,
58+
Select_GPR_Using_CC_UImm7_NDS,
5759
Select_FPR16_Using_CC_GPR,
5860
Select_FPR16INX_Using_CC_GPR,
5961
Select_FPR32_Using_CC_GPR,

llvm/test/CodeGen/RISCV/rv32xandesperf.ll

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
define i32 @bbc(i32 %a) nounwind {
88
; CHECK-LABEL: bbc:
99
; CHECK: # %bb.0:
10-
; CHECK-NEXT: slli a0, a0, 15
11-
; CHECK-NEXT: bgez a0, .LBB0_2
10+
; CHECK-NEXT: nds.bbc a0, 16, .LBB0_2
1211
; CHECK-NEXT: j .LBB0_1
1312
; CHECK-NEXT: .LBB0_1: # %f
1413
; CHECK-NEXT: li a0, 0
@@ -31,9 +30,8 @@ define i32 @select_bbc(i32 %a, i32 %b, i32 %c) nounwind {
3130
; CHECK: # %bb.0:
3231
; CHECK-NEXT: addi sp, sp, -16
3332
; CHECK-NEXT: sw a2, 8(sp) # 4-byte Folded Spill
34-
; CHECK-NEXT: slli a0, a0, 15
3533
; CHECK-NEXT: sw a1, 12(sp) # 4-byte Folded Spill
36-
; CHECK-NEXT: bgez a0, .LBB1_2
34+
; CHECK-NEXT: nds.bbc a0, 16, .LBB1_2
3735
; CHECK-NEXT: # %bb.1:
3836
; CHECK-NEXT: lw a0, 8(sp) # 4-byte Folded Reload
3937
; CHECK-NEXT: sw a0, 12(sp) # 4-byte Folded Spill
@@ -53,8 +51,7 @@ define i32 @select_bbc(i32 %a, i32 %b, i32 %c) nounwind {
5351
define i32 @bbs(i32 %a) nounwind {
5452
; CHECK-LABEL: bbs:
5553
; CHECK: # %bb.0:
56-
; CHECK-NEXT: slli a0, a0, 15
57-
; CHECK-NEXT: bltz a0, .LBB2_2
54+
; CHECK-NEXT: nds.bbs a0, 16, .LBB2_2
5855
; CHECK-NEXT: j .LBB2_1
5956
; CHECK-NEXT: .LBB2_1: # %f
6057
; CHECK-NEXT: li a0, 0
@@ -77,9 +74,8 @@ define i32 @select_bbs(i32 %a, i32 %b, i32 %c) nounwind {
7774
; CHECK: # %bb.0:
7875
; CHECK-NEXT: addi sp, sp, -16
7976
; CHECK-NEXT: sw a2, 8(sp) # 4-byte Folded Spill
80-
; CHECK-NEXT: slli a0, a0, 15
8177
; CHECK-NEXT: sw a1, 12(sp) # 4-byte Folded Spill
82-
; CHECK-NEXT: bltz a0, .LBB3_2
78+
; CHECK-NEXT: nds.bbs a0, 16, .LBB3_2
8379
; CHECK-NEXT: # %bb.1:
8480
; CHECK-NEXT: lw a0, 8(sp) # 4-byte Folded Reload
8581
; CHECK-NEXT: sw a0, 12(sp) # 4-byte Folded Spill
@@ -99,8 +95,7 @@ define i32 @select_bbs(i32 %a, i32 %b, i32 %c) nounwind {
9995
define i32 @beqc(i32 %a) nounwind {
10096
; CHECK-LABEL: beqc:
10197
; CHECK: # %bb.0:
102-
; CHECK-NEXT: li a1, 5
103-
; CHECK-NEXT: beq a0, a1, .LBB4_2
98+
; CHECK-NEXT: nds.beqc a0, 5, .LBB4_2
10499
; CHECK-NEXT: j .LBB4_1
105100
; CHECK-NEXT: .LBB4_1: # %f
106101
; CHECK-NEXT: li a0, 0
@@ -121,10 +116,8 @@ define i32 @select_beqc(i32 %a, i32 %b, i32 %c) nounwind {
121116
; CHECK: # %bb.0:
122117
; CHECK-NEXT: addi sp, sp, -16
123118
; CHECK-NEXT: sw a2, 8(sp) # 4-byte Folded Spill
124-
; CHECK-NEXT: mv a2, a1
125-
; CHECK-NEXT: li a1, 5
126-
; CHECK-NEXT: sw a2, 12(sp) # 4-byte Folded Spill
127-
; CHECK-NEXT: beq a0, a1, .LBB5_2
119+
; CHECK-NEXT: sw a1, 12(sp) # 4-byte Folded Spill
120+
; CHECK-NEXT: nds.beqc a0, 5, .LBB5_2
128121
; CHECK-NEXT: # %bb.1:
129122
; CHECK-NEXT: lw a0, 8(sp) # 4-byte Folded Reload
130123
; CHECK-NEXT: sw a0, 12(sp) # 4-byte Folded Spill
@@ -142,8 +135,7 @@ define i32 @select_beqc(i32 %a, i32 %b, i32 %c) nounwind {
142135
define i32 @bnec(i32 %a) nounwind {
143136
; CHECK-LABEL: bnec:
144137
; CHECK: # %bb.0:
145-
; CHECK-NEXT: li a1, 5
146-
; CHECK-NEXT: bne a0, a1, .LBB6_2
138+
; CHECK-NEXT: nds.bnec a0, 5, .LBB6_2
147139
; CHECK-NEXT: j .LBB6_1
148140
; CHECK-NEXT: .LBB6_1: # %f
149141
; CHECK-NEXT: li a0, 0
@@ -164,10 +156,8 @@ define i32 @select_bnec(i32 %a, i32 %b, i32 %c) nounwind {
164156
; CHECK: # %bb.0:
165157
; CHECK-NEXT: addi sp, sp, -16
166158
; CHECK-NEXT: sw a2, 8(sp) # 4-byte Folded Spill
167-
; CHECK-NEXT: mv a2, a1
168-
; CHECK-NEXT: li a1, 5
169-
; CHECK-NEXT: sw a2, 12(sp) # 4-byte Folded Spill
170-
; CHECK-NEXT: bne a0, a1, .LBB7_2
159+
; CHECK-NEXT: sw a1, 12(sp) # 4-byte Folded Spill
160+
; CHECK-NEXT: nds.bnec a0, 5, .LBB7_2
171161
; CHECK-NEXT: # %bb.1:
172162
; CHECK-NEXT: lw a0, 8(sp) # 4-byte Folded Reload
173163
; CHECK-NEXT: sw a0, 12(sp) # 4-byte Folded Spill

0 commit comments

Comments
 (0)