Skip to content

[RISCV][NFC] Convert some predicates to TIIPredicate #129658

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 30, 2025

Conversation

wangpc-pp
Copy link
Contributor

@wangpc-pp wangpc-pp commented Mar 4, 2025

These predicates can also be used in macro fusion and scheduling
model.

@llvmbot
Copy link
Member

llvmbot commented Mar 4, 2025

@llvm/pr-subscribers-tablegen

@llvm/pr-subscribers-backend-risc-v

Author: Pengcheng Wang (wangpc-pp)

Changes

These predicates can also be used in macro fusion and scheduling
model.


Full diff: https://github.com/llvm/llvm-project/pull/129658.diff

7 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCV.td (+6)
  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+2-19)
  • (modified) llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp (+11-25)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.cpp (+6-21)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.h (+3-5)
  • (added) llvm/lib/Target/RISCV/RISCVInstrPredicates.td (+73)
  • (modified) llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp (+1-1)
diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
index 2c2271e486a84..6ecf6460d1e32 100644
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -36,6 +36,12 @@ include "RISCVCallingConv.td"
 include "RISCVInstrInfo.td"
 include "GISel/RISCVRegisterBanks.td"
 
+//===----------------------------------------------------------------------===//
+// Instruction predicates
+//===----------------------------------------------------------------------===//
+
+include "RISCVInstrPredicates.td"
+
 //===----------------------------------------------------------------------===//
 // RISC-V macro fusions.
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 4e6b3a224b79b..0a4a5f510c392 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -19909,23 +19909,6 @@ static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI,
   return BB;
 }
 
-static bool isSelectPseudo(MachineInstr &MI) {
-  switch (MI.getOpcode()) {
-  default:
-    return false;
-  case RISCV::Select_GPR_Using_CC_GPR:
-  case RISCV::Select_GPR_Using_CC_Imm:
-  case RISCV::Select_FPR16_Using_CC_GPR:
-  case RISCV::Select_FPR16INX_Using_CC_GPR:
-  case RISCV::Select_FPR32_Using_CC_GPR:
-  case RISCV::Select_FPR32INX_Using_CC_GPR:
-  case RISCV::Select_FPR64_Using_CC_GPR:
-  case RISCV::Select_FPR64INX_Using_CC_GPR:
-  case RISCV::Select_FPR64IN32X_Using_CC_GPR:
-    return true;
-  }
-}
-
 static MachineBasicBlock *emitQuietFCMP(MachineInstr &MI, MachineBasicBlock *BB,
                                         unsigned RelOpcode, unsigned EqOpcode,
                                         const RISCVSubtarget &Subtarget) {
@@ -20121,7 +20104,7 @@ static MachineBasicBlock *emitSelectPseudo(MachineInstr &MI,
        SequenceMBBI != E; ++SequenceMBBI) {
     if (SequenceMBBI->isDebugInstr())
       continue;
-    if (isSelectPseudo(*SequenceMBBI)) {
+    if (RISCVInstrInfo::isSelectPseudo(*SequenceMBBI)) {
       if (SequenceMBBI->getOperand(1).getReg() != LHS ||
           !SequenceMBBI->getOperand(2).isReg() ||
           SequenceMBBI->getOperand(2).getReg() != RHS ||
@@ -20198,7 +20181,7 @@ static MachineBasicBlock *emitSelectPseudo(MachineInstr &MI,
   auto InsertionPoint = TailMBB->begin();
   while (SelectMBBI != SelectEnd) {
     auto Next = std::next(SelectMBBI);
-    if (isSelectPseudo(*SelectMBBI)) {
+    if (RISCVInstrInfo::isSelectPseudo(*SelectMBBI)) {
       // %Result = phi [ %TrueValue, HeadMBB ], [ %FalseValue, IfFalseMBB ]
       BuildMI(*TailMBB, InsertionPoint, SelectMBBI->getDebugLoc(),
               TII.get(RISCV::PHI), SelectMBBI->getOperand(0).getReg())
diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index 7433603daff85..73a03d66cecd7 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -69,21 +69,6 @@ static unsigned getSEWOpNum(const MachineInstr &MI) {
   return RISCVII::getSEWOpNum(MI.getDesc());
 }
 
-static bool isVectorConfigInstr(const MachineInstr &MI) {
-  return MI.getOpcode() == RISCV::PseudoVSETVLI ||
-         MI.getOpcode() == RISCV::PseudoVSETVLIX0 ||
-         MI.getOpcode() == RISCV::PseudoVSETIVLI;
-}
-
-/// Return true if this is 'vsetvli x0, x0, vtype' which preserves
-/// VL and only sets VTYPE.
-static bool isVLPreservingConfig(const MachineInstr &MI) {
-  if (MI.getOpcode() != RISCV::PseudoVSETVLIX0)
-    return false;
-  assert(RISCV::X0 == MI.getOperand(1).getReg());
-  return RISCV::X0 == MI.getOperand(0).getReg();
-}
-
 static bool isFloatScalarMoveOrScalarSplatInstr(const MachineInstr &MI) {
   switch (RISCV::getRVVMCOpcode(MI.getOpcode())) {
   default:
@@ -979,7 +964,7 @@ void RISCVInsertVSETVLI::forwardVSETVLIAVL(VSETVLIInfo &Info) const {
   if (!Info.hasAVLReg())
     return;
   const MachineInstr *DefMI = Info.getAVLDefMI(LIS);
-  if (!DefMI || !isVectorConfigInstr(*DefMI))
+  if (!DefMI || !RISCVInstrInfo::isVectorConfigInstr(*DefMI))
     return;
   VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(*DefMI);
   if (!DefInstrInfo.hasSameVLMAX(Info))
@@ -1126,7 +1111,7 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
     // same, we can use the X0, X0 form.
     if (Info.hasSameVLMAX(PrevInfo) && Info.hasAVLReg()) {
       if (const MachineInstr *DefMI = Info.getAVLDefMI(LIS);
-          DefMI && isVectorConfigInstr(*DefMI)) {
+          DefMI && RISCVInstrInfo::isVectorConfigInstr(*DefMI)) {
         VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI);
         if (DefInfo.hasSameAVL(PrevInfo) && DefInfo.hasSameVLMAX(PrevInfo)) {
           auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0))
@@ -1304,7 +1289,7 @@ void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info,
 // reflect the changes MI might make.
 void RISCVInsertVSETVLI::transferAfter(VSETVLIInfo &Info,
                                        const MachineInstr &MI) const {
-  if (isVectorConfigInstr(MI)) {
+  if (RISCVInstrInfo::isVectorConfigInstr(MI)) {
     Info = getInfoForVSETVLI(MI);
     return;
   }
@@ -1339,7 +1324,8 @@ bool RISCVInsertVSETVLI::computeVLVTYPEChanges(const MachineBasicBlock &MBB,
   for (const MachineInstr &MI : MBB) {
     transferBefore(Info, MI);
 
-    if (isVectorConfigInstr(MI) || RISCVII::hasSEWOp(MI.getDesc().TSFlags) ||
+    if (RISCVInstrInfo::isVectorConfigInstr(MI) ||
+        RISCVII::hasSEWOp(MI.getDesc().TSFlags) ||
         isVectorCopy(ST->getRegisterInfo(), MI))
       HadVectorOp = true;
 
@@ -1429,7 +1415,7 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require,
     if (!Value)
       return true;
     MachineInstr *DefMI = LIS->getInstructionFromIndex(Value->def);
-    if (!DefMI || !isVectorConfigInstr(*DefMI))
+    if (!DefMI || !RISCVInstrInfo::isVectorConfigInstr(*DefMI))
       return true;
 
     // We found a VSET(I)VLI make sure it matches the output of the
@@ -1460,7 +1446,7 @@ void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) {
     transferBefore(CurInfo, MI);
 
     // If this is an explicit VSETVLI or VSETIVLI, update our state.
-    if (isVectorConfigInstr(MI)) {
+    if (RISCVInstrInfo::isVectorConfigInstr(MI)) {
       // Conservatively, mark the VL and VTYPE as live.
       assert(MI.getOperand(3).getReg() == RISCV::VL &&
              MI.getOperand(4).getReg() == RISCV::VTYPE &&
@@ -1660,12 +1646,12 @@ bool RISCVInsertVSETVLI::canMutatePriorConfig(
   // If the VL values aren't equal, return false if either a) the former is
   // demanded, or b) we can't rewrite the former to be the later for
   // implementation reasons.
-  if (!isVLPreservingConfig(MI)) {
+  if (!RISCVInstrInfo::isVLPreservingConfig(MI)) {
     if (Used.VLAny)
       return false;
 
     if (Used.VLZeroness) {
-      if (isVLPreservingConfig(PrevMI))
+      if (RISCVInstrInfo::isVLPreservingConfig(PrevMI))
         return false;
       if (!getInfoForVSETVLI(PrevMI).hasEquallyZeroAVL(getInfoForVSETVLI(MI),
                                                        LIS))
@@ -1716,7 +1702,7 @@ void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
 
   for (MachineInstr &MI : make_early_inc_range(reverse(MBB))) {
 
-    if (!isVectorConfigInstr(MI)) {
+    if (!RISCVInstrInfo::isVectorConfigInstr(MI)) {
       Used.doUnion(getDemanded(MI, ST));
       if (MI.isCall() || MI.isInlineAsm() ||
           MI.modifiesRegister(RISCV::VL, /*TRI=*/nullptr) ||
@@ -1740,7 +1726,7 @@ void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
       }
 
       if (canMutatePriorConfig(MI, *NextMI, Used)) {
-        if (!isVLPreservingConfig(*NextMI)) {
+        if (!RISCVInstrInfo::isVLPreservingConfig(*NextMI)) {
           Register DefReg = NextMI->getOperand(0).getReg();
 
           MI.getOperand(0).setReg(DefReg);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index bca508e2136ab..6ef6684ca0e23 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -77,6 +77,9 @@ RISCVInstrInfo::RISCVInstrInfo(RISCVSubtarget &STI)
     : RISCVGenInstrInfo(RISCV::ADJCALLSTACKDOWN, RISCV::ADJCALLSTACKUP),
       STI(STI) {}
 
+#define GET_INSTRINFO_HELPERS
+#include "RISCVGenInstrInfo.inc"
+
 MCInst RISCVInstrInfo::getNop() const {
   if (STI.hasStdExtCOrZca())
     return MCInstBuilder(RISCV::C_NOP);
@@ -777,15 +780,15 @@ MachineInstr *RISCVInstrInfo::foldMemoryOperandImpl(
   unsigned LoadOpc;
   switch (MI.getOpcode()) {
   default:
-    if (RISCV::isSEXT_W(MI)) {
+    if (RISCVInstrInfo::isSEXT_W(MI)) {
       LoadOpc = RISCV::LW;
       break;
     }
-    if (RISCV::isZEXT_W(MI)) {
+    if (RISCVInstrInfo::isZEXT_W(MI)) {
       LoadOpc = RISCV::LWU;
       break;
     }
-    if (RISCV::isZEXT_B(MI)) {
+    if (RISCVInstrInfo::isZEXT_B(MI)) {
       LoadOpc = RISCV::LBU;
       break;
     }
@@ -3991,24 +3994,6 @@ unsigned RISCVInstrInfo::getTailDuplicateSize(CodeGenOptLevel OptLevel) const {
              : 2;
 }
 
-// Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
-bool RISCV::isSEXT_W(const MachineInstr &MI) {
-  return MI.getOpcode() == RISCV::ADDIW && MI.getOperand(1).isReg() &&
-         MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0;
-}
-
-// Returns true if this is the zext.w pattern, adduw rd, rs1, x0.
-bool RISCV::isZEXT_W(const MachineInstr &MI) {
-  return MI.getOpcode() == RISCV::ADD_UW && MI.getOperand(1).isReg() &&
-         MI.getOperand(2).isReg() && MI.getOperand(2).getReg() == RISCV::X0;
-}
-
-// Returns true if this is the zext.b pattern, andi rd, rs1, 255.
-bool RISCV::isZEXT_B(const MachineInstr &MI) {
-  return MI.getOpcode() == RISCV::ANDI && MI.getOperand(1).isReg() &&
-         MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 255;
-}
-
 static bool isRVVWholeLoadStore(unsigned Opcode) {
   switch (Opcode) {
   default:
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
index 1c46d761a7e1e..0a0ad51c386fb 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
@@ -301,6 +301,9 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {
 
   bool isHighLatencyDef(int Opc) const override;
 
+#define GET_INSTRINFO_HELPER_DECLS
+#include "RISCVGenInstrInfo.inc"
+
 protected:
   const RISCVSubtarget &STI;
 
@@ -317,11 +320,6 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {
 
 namespace RISCV {
 
-// Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
-bool isSEXT_W(const MachineInstr &MI);
-bool isZEXT_W(const MachineInstr &MI);
-bool isZEXT_B(const MachineInstr &MI);
-
 // Returns true if the given MI is an RVV instruction opcode for which we may
 // expect to see a FrameIndex operand.
 bool isRVVSpill(const MachineInstr &MI);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrPredicates.td b/llvm/lib/Target/RISCV/RISCVInstrPredicates.td
new file mode 100644
index 0000000000000..2b2ec22fff87f
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrPredicates.td
@@ -0,0 +1,73 @@
+//===-- RISCVInstrPredicates.td - Instruction Predicates ---*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the RISC-V instruction predicates.
+//
+//===----------------------------------------------------------------------===//
+
+// Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
+def isSEXT_W : TIIPredicate<"isSEXT_W",
+                            MCReturnStatement<CheckAll<[
+                              CheckOpcode<[ADDIW]>,
+                              CheckIsRegOperand<1>,
+                              CheckIsImmOperand<2>,
+                              CheckImmOperand<2, 0>
+                            ]>>>;
+
+// Returns true if this is the zext.w pattern, adduw rd, rs1, x0.
+def isZEXT_W : TIIPredicate<"isZEXT_W",
+                            MCReturnStatement<CheckAll<[
+                              CheckOpcode<[ADD_UW]>,
+                              CheckIsRegOperand<1>,
+                              CheckIsRegOperand<2>,
+                              CheckRegOperand<2, X0>
+                            ]>>>;
+
+// Returns true if this is the zext.b pattern, andi rd, rs1, 255.
+def isZEXT_B : TIIPredicate<"isZEXT_B",
+                            MCReturnStatement<CheckAll<[
+                              CheckOpcode<[ANDI]>,
+                              CheckIsRegOperand<1>,
+                              CheckIsImmOperand<2>,
+                              CheckImmOperand<2, 255>
+                            ]>>>;
+
+// Returns true if this is the zext.b pattern, andi rd, rs1, 255.
+def isSelectPseudo : TIIPredicate<"isSelectPseudo",
+                                  MCOpcodeSwitchStatement<
+                                    [MCOpcodeSwitchCase<
+                                       [Select_GPR_Using_CC_GPR,
+                                        Select_GPR_Using_CC_Imm,
+                                        Select_FPR16_Using_CC_GPR,
+                                        Select_FPR16INX_Using_CC_GPR,
+                                        Select_FPR32_Using_CC_GPR,
+                                        Select_FPR32INX_Using_CC_GPR,
+                                        Select_FPR64_Using_CC_GPR,
+                                        Select_FPR64INX_Using_CC_GPR,
+                                        Select_FPR64IN32X_Using_CC_GPR
+                                       ],
+                                       MCReturnStatement<TruePred>>],
+                                     MCReturnStatement<FalsePred>>>;
+
+// Returns true if this is a vector configuration instruction.
+def isVectorConfigInstr : TIIPredicate<"isVectorConfigInstr",
+                                       MCReturnStatement<
+                                         CheckOpcode<[
+                                           PseudoVSETVLI,
+                                           PseudoVSETVLIX0,
+                                           PseudoVSETIVLI
+                                         ]>>>;
+
+/// Return true if this is 'vsetvli x0, x0, vtype' which preserves
+/// VL and only sets VTYPE.
+def isVLPreservingConfig : TIIPredicate<"isVLPreservingConfig",
+                                        MCReturnStatement<
+                                          CheckAll<[
+                                            CheckOpcode<[PseudoVSETVLIX0]>,
+                                            CheckRegOperand<0, X0>
+                                          ]>>>;
diff --git a/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
index 28bee83837654..3b601bb43bf28 100644
--- a/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
+++ b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
@@ -648,7 +648,7 @@ bool RISCVOptWInstrs::removeSExtWInstrs(MachineFunction &MF,
   for (MachineBasicBlock &MBB : MF) {
     for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
       // We're looking for the sext.w pattern ADDIW rd, rs1, 0.
-      if (!RISCV::isSEXT_W(MI))
+      if (!RISCVInstrInfo::isSEXT_W(MI))
         continue;
 
       Register SrcReg = MI.getOperand(1).getReg();

Copy link
Contributor

@lukel97 lukel97 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isVectorConfigInstr and isVLPreservingConfig LGTM. Is this NFC?

@wangpc-pp wangpc-pp force-pushed the main-riscv-instr-predicates branch from 79508c6 to 8d2c27a Compare March 4, 2025 12:14
@wangpc-pp wangpc-pp changed the title [RISCV] Convert some predicates to TIIPredicate [RISCV][NFC] Convert some predicates to TIIPredicate Mar 4, 2025
@wangpc-pp wangpc-pp force-pushed the main-riscv-instr-predicates branch from 4e3d245 to d94e5e9 Compare April 22, 2025 12:19
@wangpc-pp
Copy link
Contributor Author

Ping.

@wangpc-pp
Copy link
Contributor Author

Ping.

@topperc
Copy link
Collaborator

topperc commented Apr 29, 2025

The description only mentions that they can be used in macrofusion and scheduling, but most or all of them aren't. Is the design goal that going forward all instruction predicates will be done in .td in case they need to be used in scheduling macrofusion or scheduling?

@wangpc-pp
Copy link
Contributor Author

The description only mentions that they can be used in macrofusion and scheduling, but most or all of them aren't.

The initial cases are isSEXT_W/isZEXT_W/isZEXT_B (for fusion) and when implementing this, my thought was, why not convert all predicate-like code into TableGen? So I searched all these predicates and did this patch.

Is the design goal that going forward all instruction predicates will be done in .td in case they need to be used in scheduling macrofusion or scheduling?

Yes!

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@wangpc-pp wangpc-pp force-pushed the main-riscv-instr-predicates branch from 7d1f35f to 954a110 Compare April 30, 2025 08:50
These predicates can also be used in macro fusion and scheduling
model.
@wangpc-pp wangpc-pp force-pushed the main-riscv-instr-predicates branch from 954a110 to d18ce9f Compare April 30, 2025 08:58
@wangpc-pp wangpc-pp merged commit 8f75747 into llvm:main Apr 30, 2025
4 of 6 checks passed
@wangpc-pp wangpc-pp deleted the main-riscv-instr-predicates branch April 30, 2025 08:59
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
These predicates can also be used in macro fusion and scheduling
model.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
These predicates can also be used in macro fusion and scheduling
model.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
These predicates can also be used in macro fusion and scheduling
model.
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
These predicates can also be used in macro fusion and scheduling
model.
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request May 9, 2025
These predicates can also be used in macro fusion and scheduling
model.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants