Skip to content

Commit fa21fcb

Browse files
authored
[RISCV] Add short forward branch support for min, max, maxu and minu (llvm#164394)
1 parent 86f35da commit fa21fcb

File tree

6 files changed

+737
-3
lines changed

6 files changed

+737
-3
lines changed

llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
127127
case RISCV::PseudoCCAND:
128128
case RISCV::PseudoCCOR:
129129
case RISCV::PseudoCCXOR:
130+
case RISCV::PseudoCCMAX:
131+
case RISCV::PseudoCCMAXU:
132+
case RISCV::PseudoCCMIN:
133+
case RISCV::PseudoCCMINU:
130134
case RISCV::PseudoCCADDW:
131135
case RISCV::PseudoCCSUBW:
132136
case RISCV::PseudoCCSLL:
@@ -217,6 +221,7 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
217221
.addImm(0);
218222
} else {
219223
unsigned NewOpc;
224+
// clang-format off
220225
switch (MI.getOpcode()) {
221226
default:
222227
llvm_unreachable("Unexpected opcode!");
@@ -228,6 +233,10 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
228233
case RISCV::PseudoCCAND: NewOpc = RISCV::AND; break;
229234
case RISCV::PseudoCCOR: NewOpc = RISCV::OR; break;
230235
case RISCV::PseudoCCXOR: NewOpc = RISCV::XOR; break;
236+
case RISCV::PseudoCCMAX: NewOpc = RISCV::MAX; break;
237+
case RISCV::PseudoCCMIN: NewOpc = RISCV::MIN; break;
238+
case RISCV::PseudoCCMAXU: NewOpc = RISCV::MAXU; break;
239+
case RISCV::PseudoCCMINU: NewOpc = RISCV::MINU; break;
231240
case RISCV::PseudoCCADDI: NewOpc = RISCV::ADDI; break;
232241
case RISCV::PseudoCCSLLI: NewOpc = RISCV::SLLI; break;
233242
case RISCV::PseudoCCSRLI: NewOpc = RISCV::SRLI; break;
@@ -250,6 +259,7 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
250259
case RISCV::PseudoCCNDS_BFOS: NewOpc = RISCV::NDS_BFOS; break;
251260
case RISCV::PseudoCCNDS_BFOZ: NewOpc = RISCV::NDS_BFOZ; break;
252261
}
262+
// clang-format on
253263

254264
if (NewOpc == RISCV::NDS_BFOZ || NewOpc == RISCV::NDS_BFOS) {
255265
BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg)

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,6 +1851,11 @@ def TuneShortForwardBranchOpt
18511851
def HasShortForwardBranchOpt : Predicate<"Subtarget->hasShortForwardBranchOpt()">;
18521852
def NoShortForwardBranchOpt : Predicate<"!Subtarget->hasShortForwardBranchOpt()">;
18531853

1854+
def TuneShortForwardBranchIMinMax
1855+
: SubtargetFeature<"short-forward-branch-i-minmax", "HasShortForwardBranchIMinMax",
1856+
"true", "Enable short forward branch optimization for min,max instructions in Zbb",
1857+
[TuneShortForwardBranchOpt]>;
1858+
18541859
// Some subtargets require a S2V transfer buffer to move scalars into vectors.
18551860
// FIXME: Forming .vx/.vf/.wx/.wf can reduce register pressure.
18561861
def TuneNoSinkSplatOperands

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,6 +1699,10 @@ unsigned getPredicatedOpcode(unsigned Opcode) {
16991699
case RISCV::AND: return RISCV::PseudoCCAND;
17001700
case RISCV::OR: return RISCV::PseudoCCOR;
17011701
case RISCV::XOR: return RISCV::PseudoCCXOR;
1702+
case RISCV::MAX: return RISCV::PseudoCCMAX;
1703+
case RISCV::MAXU: return RISCV::PseudoCCMAXU;
1704+
case RISCV::MIN: return RISCV::PseudoCCMIN;
1705+
case RISCV::MINU: return RISCV::PseudoCCMINU;
17021706

17031707
case RISCV::ADDI: return RISCV::PseudoCCADDI;
17041708
case RISCV::SLLI: return RISCV::PseudoCCSLLI;
@@ -1735,14 +1739,21 @@ unsigned getPredicatedOpcode(unsigned Opcode) {
17351739
/// return the defining instruction.
17361740
static MachineInstr *canFoldAsPredicatedOp(Register Reg,
17371741
const MachineRegisterInfo &MRI,
1738-
const TargetInstrInfo *TII) {
1742+
const TargetInstrInfo *TII,
1743+
const RISCVSubtarget &STI) {
17391744
if (!Reg.isVirtual())
17401745
return nullptr;
17411746
if (!MRI.hasOneNonDBGUse(Reg))
17421747
return nullptr;
17431748
MachineInstr *MI = MRI.getVRegDef(Reg);
17441749
if (!MI)
17451750
return nullptr;
1751+
1752+
if (!STI.hasShortForwardBranchIMinMax() &&
1753+
(MI->getOpcode() == RISCV::MAX || MI->getOpcode() == RISCV::MIN ||
1754+
MI->getOpcode() == RISCV::MINU || MI->getOpcode() == RISCV::MAXU))
1755+
return nullptr;
1756+
17461757
// Check if MI can be predicated and folded into the CCMOV.
17471758
if (getPredicatedOpcode(MI->getOpcode()) == RISCV::INSTRUCTION_LIST_END)
17481759
return nullptr;
@@ -1806,10 +1817,10 @@ RISCVInstrInfo::optimizeSelect(MachineInstr &MI,
18061817

18071818
MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
18081819
MachineInstr *DefMI =
1809-
canFoldAsPredicatedOp(MI.getOperand(5).getReg(), MRI, this);
1820+
canFoldAsPredicatedOp(MI.getOperand(5).getReg(), MRI, this, STI);
18101821
bool Invert = !DefMI;
18111822
if (!DefMI)
1812-
DefMI = canFoldAsPredicatedOp(MI.getOperand(4).getReg(), MRI, this);
1823+
DefMI = canFoldAsPredicatedOp(MI.getOperand(4).getReg(), MRI, this, STI);
18131824
if (!DefMI)
18141825
return nullptr;
18151826

llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ def PseudoCCSRA : SFBALU_rr;
106106
def PseudoCCAND : SFBALU_rr;
107107
def PseudoCCOR : SFBALU_rr;
108108
def PseudoCCXOR : SFBALU_rr;
109+
def PseudoCCMAX : SFBALU_rr;
110+
def PseudoCCMIN : SFBALU_rr;
111+
def PseudoCCMAXU : SFBALU_rr;
112+
def PseudoCCMINU : SFBALU_rr;
109113

110114
def PseudoCCADDI : SFBALU_ri;
111115
def PseudoCCANDI : SFBALU_ri;

llvm/test/CodeGen/RISCV/features-info.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
; CHECK-NEXT: shgatpa - 'Shgatpa' (SvNNx4 mode supported for all modes supported by satp, as well as Bare).
137137
; CHECK-NEXT: shifted-zextw-fusion - Enable SLLI+SRLI to be fused when computing (shifted) word zero extension.
138138
; CHECK-NEXT: shlcofideleg - 'Shlcofideleg' (Delegating LCOFI Interrupts to VS-mode).
139+
; CHECK-NEXT: short-forward-branch-i-minmax - Enable short forward branch optimization for min,max instructions in Zbb.
139140
; CHECK-NEXT: short-forward-branch-opt - Enable short forward branch optimization.
140141
; CHECK-NEXT: shtvala - 'Shtvala' (htval provides all needed values).
141142
; CHECK-NEXT: shvsatpa - 'Shvsatpa' (vsatp supports all modes supported by satp).

0 commit comments

Comments
 (0)