llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang

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

Author: Boyao Wang (BoyaoWang430)

<details>
<summary>Changes</summary>

This adds the CodeGen support of Zibi v0.1 experimental extension, which 
depends on #<!-- -->127463. The first commit is from the base PR.

---

Patch is 32.58 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/146858.diff


23 Files Affected:

- (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1) 
- (modified) clang/test/Preprocessor/riscv-target-features.c (+9) 
- (modified) llvm/docs/RISCVUsage.rst (+3) 
- (modified) llvm/docs/ReleaseNotes.md (+2) 
- (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+9) 
- (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+8) 
- (modified) llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp (+3-2) 
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (+1) 
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp (+17) 
- (modified) llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp (+1-1) 
- (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+6) 
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+7-4) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrFormats.td (+16) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.cpp (+18-4) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.h (+2-1) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.td (+1) 
- (added) llvm/lib/Target/RISCV/RISCVInstrInfoZibi.td (+51) 
- (modified) llvm/test/CodeGen/RISCV/attributes.ll (+4) 
- (modified) llvm/test/CodeGen/RISCV/features-info.ll (+1) 
- (added) llvm/test/CodeGen/RISCV/zibi.ll (+198) 
- (added) llvm/test/MC/RISCV/zibi-invalid.s (+34) 
- (added) llvm/test/MC/RISCV/zibi-valid.s (+63) 
- (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1) 


``````````diff
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c 
b/clang/test/Driver/print-supported-extensions-riscv.c
index 314fdad7e52e7..a703948316298 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -205,6 +205,7 @@
 // CHECK-EMPTY:
 // CHECK-NEXT: Experimental extensions
 // CHECK-NEXT:     p                    0.14      'P' ('Base P' (Packed SIMD))
+// CHECK-NEXT:     zibi                 0.1       'Zibi' (Branch with 
Immediate)
 // CHECK-NEXT:     zicfilp              1.0       'Zicfilp' (Landing pad)
 // CHECK-NEXT:     zicfiss              1.0       'Zicfiss' (Shadow stack)
 // CHECK-NEXT:     zalasr               0.1       'Zalasr' (Load-Acquire and 
Store-Release Instructions)
diff --git a/clang/test/Preprocessor/riscv-target-features.c 
b/clang/test/Preprocessor/riscv-target-features.c
index 86085c21a95aa..52a483100f829 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -122,6 +122,7 @@
 // CHECK-NOT: __riscv_zfinx {{.*$}}
 // CHECK-NOT: __riscv_zhinx {{.*$}}
 // CHECK-NOT: __riscv_zhinxmin {{.*$}}
+// CHECK-NOT: __riscv_zibi {{.*$}}
 // CHECK-NOT: __riscv_zic64b {{.*$}}
 // CHECK-NOT: __riscv_zicbom {{.*$}}
 // CHECK-NOT: __riscv_zicbop {{.*$}}
@@ -1029,6 +1030,14 @@
 // RUN:   -o - | FileCheck --check-prefix=CHECK-ZHINXMIN-EXT %s
 // CHECK-ZHINXMIN-EXT: __riscv_zhinxmin 1000000{{$}}
 
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32i_zibi0p1 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-ZIBI-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN:   -march=rv64i_zibi0p1 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-ZIBI-EXT %s
+// CHECK-ZIBI-EXT: __riscv_zibi
+
 // RUN: %clang --target=riscv32-unknown-linux-gnu \
 // RUN:   -march=rv32izic64b -E -dM %s \
 // RUN:   -o - | FileCheck --check-prefix=CHECK-ZIC64B-EXT %s
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 81684ba30f12c..b04f65974b0d0 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -326,6 +326,9 @@ The primary goal of experimental support is to assist in 
the process of ratifica
 ``experimental-zalasr``
   LLVM implements the `0.0.5 draft specification 
<https://github.com/mehnadnerd/riscv-zalasr>`__.
 
+``experimental-zibi``
+  LLVM implements the `0.1 release specification 
<https://lf-riscv.atlassian.net/wiki/spaces/USXX/pages/599261201/Branch+with+Immediate+Zibi+Ratification+Plan>`__.
+
 ``experimental-zicfilp``, ``experimental-zicfiss``
   LLVM implements the `1.0 release specification 
<https://github.com/riscv/riscv-cfi/releases/tag/v1.0>`__.
 
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 26384d94d04fc..7bb4138b288b2 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -177,6 +177,8 @@ Changes to the RISC-V Backend
   extension.
 * Adds experimental assembler support for the Qualcomm uC 'Xqciio` (External 
Input Output)
   extension.
+* Adds experimental assembler and code generation support for the 'Zibi` 
(Branch with Immediate)
+  extension.
 * Adds assembler support for the 'Zilsd` (Load/Store Pair Instructions)
   extension.
 * Adds assembler support for the 'Zclsd` (Compressed Load/Store Pair 
Instructions)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp 
b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index bb0f9df2032fd..f239bdfbb208a 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -744,6 +744,11 @@ struct RISCVOperand final : public MCParsedAsmOperand {
     return isUImmPred([](int64_t Imm) { return Imm != 0 && isUInt<5>(Imm); });
   }
 
+  bool isUImm5Zibi() const {
+    return isUImmPred(
+        [](int64_t Imm) { return (Imm != 0 && isUInt<5>(Imm)) || Imm == -1; });
+  }
+
   bool isUImm5GT3() const {
     return isUImmPred([](int64_t Imm) { return isUInt<5>(Imm) && Imm > 3; });
   }
@@ -1470,6 +1475,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc 
IDLoc, unsigned &Opcode,
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
   case Match_InvalidUImm5NonZero:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
+  case Match_InvalidUImm5Zibi:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, -1, (1 << 5) - 1,
+        "immediate must be non-zero in the range");
   case Match_InvalidUImm5GT3:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
   case Match_InvalidUImm5Plus1:
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp 
b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 52061e96d0018..72c3415d3ea2e 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -457,6 +457,14 @@ static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, 
uint32_t Imm,
   return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
 }
 
+static DecodeStatus decodeUImmZibiOperand(MCInst &Inst, uint32_t Imm,
+                                          int64_t Address,
+                                          const MCDisassembler *Decoder) {
+  assert(isUInt<5>(Imm) && "Invalid immediate");
+  Inst.addOperand(MCOperand::createImm(Imm ? Imm : -1LL));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus
 decodeUImmLog2XLenNonZeroOperand(MCInst &Inst, uint32_t Imm, int64_t Address,
                                  const MCDisassembler *Decoder) {
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp 
b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index f83c2b6da8923..0f3e080831a05 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -789,8 +789,9 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
     RISCVCC::CondCode CC;
     getOperandsForBranch(MI.getOperand(0).getReg(), CC, LHS, RHS, *MRI);
 
-    auto Bcc = MIB.buildInstr(RISCVCC::getBrCond(CC), {}, {LHS, RHS})
-                   .addMBB(MI.getOperand(1).getMBB());
+    auto Bcc =
+        MIB.buildInstr(RISCVCC::getBrCond(*Subtarget, CC), {}, {LHS, RHS})
+            .addMBB(MI.getOperand(1).getMBB());
     MI.eraseFromParent();
     return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
   }
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h 
b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index d296f76ad10ca..96733ea2d40a6 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -301,6 +301,7 @@ enum OperandType : unsigned {
   OPERAND_UIMM4,
   OPERAND_UIMM5,
   OPERAND_UIMM5_NONZERO,
+  OPERAND_UIMM5_ZIBI,
   OPERAND_UIMM5_GT3,
   OPERAND_UIMM5_PLUS1,
   OPERAND_UIMM5_GE6_PLUS1,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp 
b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index ce0fbc0ac0654..d6fd6a9323dd4 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -97,6 +97,10 @@ class RISCVMCCodeEmitter : public MCCodeEmitter {
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
 
+  uint64_t getImmOpValueZibi(const MCInst &MI, unsigned OpNo,
+                             SmallVectorImpl<MCFixup> &Fixups,
+                             const MCSubtargetInfo &STI) const;
+
   uint64_t getImmOpValue(const MCInst &MI, unsigned OpNo,
                          SmallVectorImpl<MCFixup> &Fixups,
                          const MCSubtargetInfo &STI) const;
@@ -545,6 +549,19 @@ RISCVMCCodeEmitter::getImmOpValueAsrN(const MCInst &MI, 
unsigned OpNo,
   return getImmOpValue(MI, OpNo, Fixups, STI);
 }
 
+uint64_t
+RISCVMCCodeEmitter::getImmOpValueZibi(const MCInst &MI, unsigned OpNo,
+                                      SmallVectorImpl<MCFixup> &Fixups,
+                                      const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(OpNo);
+  assert(MO.isImm() && "Zibi operand must be an immediate");
+  int64_t Res = MO.getImm();
+  if (Res == -1)
+    return 0;
+
+  return Res;
+}
+
 uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
                                            SmallVectorImpl<MCFixup> &Fixups,
                                            const MCSubtargetInfo &STI) const {
diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp 
b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
index cb57c4377779f..685215b64ba92 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
@@ -196,7 +196,7 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
   CC = RISCVCC::getOppositeBranchCondition(CC);
 
   // Insert branch instruction.
-  BuildMI(MBB, MBBI, DL, TII->get(RISCVCC::getBrCond(CC)))
+  BuildMI(MBB, MBBI, DL, TII->get(RISCVCC::getBrCond(*STI, CC)))
       .addReg(MI.getOperand(1).getReg())
       .addReg(MI.getOperand(2).getReg())
       .addMBB(MergeBB);
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td 
b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 6e103dd7d8c44..fafb50ded37aa 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -78,6 +78,12 @@ def FeatureStdExtE
     : RISCVExtension<2, 0, "Embedded Instruction Set with 16 GPRs">,
       RISCVExtensionBitmask<0, 4>;
 
+def FeatureStdExtZibi
+    : RISCVExperimentalExtension<0, 1, "Branch with Immediate">;
+def HasStdExtZibi : Predicate<"Subtarget->hasStdExtZibi()">,
+                      AssemblerPredicate<(all_of FeatureStdExtZibi),
+                                         "'Zibi' (Branch with Immediate)">;
+
 def FeatureStdExtZic64b
     : RISCVExtension<1, 0, "Cache Block Size Is 64 Bytes">;
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 30758345ab0f6..231a6560272fb 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21388,7 +21388,8 @@ EmitLoweredCascadedSelect(MachineInstr &First, 
MachineInstr &Second,
   Register FLHS = First.getOperand(1).getReg();
   Register FRHS = First.getOperand(2).getReg();
   // Insert appropriate branch.
-  BuildMI(FirstMBB, DL, TII.get(RISCVCC::getBrCond(FirstCC, 
First.getOpcode())))
+  BuildMI(FirstMBB, DL,
+          TII.get(RISCVCC::getBrCond(Subtarget, FirstCC, First.getOpcode())))
       .addReg(FLHS)
       .addReg(FRHS)
       .addMBB(SinkMBB);
@@ -21401,7 +21402,7 @@ EmitLoweredCascadedSelect(MachineInstr &First, 
MachineInstr &Second,
   auto SecondCC = 
static_cast<RISCVCC::CondCode>(Second.getOperand(3).getImm());
   // Insert appropriate branch.
   BuildMI(ThisMBB, DL,
-          TII.get(RISCVCC::getBrCond(SecondCC, Second.getOpcode())))
+          TII.get(RISCVCC::getBrCond(Subtarget, SecondCC, Second.getOpcode())))
       .addReg(SLHS)
       .addReg(SRHS)
       .addMBB(SinkMBB);
@@ -21536,12 +21537,14 @@ static MachineBasicBlock 
*emitSelectPseudo(MachineInstr &MI,
 
   // Insert appropriate branch.
   if (MI.getOperand(2).isImm())
-    BuildMI(HeadMBB, DL, TII.get(RISCVCC::getBrCond(CC, MI.getOpcode())))
+    BuildMI(HeadMBB, DL,
+            TII.get(RISCVCC::getBrCond(Subtarget, CC, MI.getOpcode(), true)))
         .addReg(LHS)
         .addImm(MI.getOperand(2).getImm())
         .addMBB(TailMBB);
   else
-    BuildMI(HeadMBB, DL, TII.get(RISCVCC::getBrCond(CC, MI.getOpcode())))
+    BuildMI(HeadMBB, DL,
+            TII.get(RISCVCC::getBrCond(Subtarget, CC, MI.getOpcode())))
         .addReg(LHS)
         .addReg(RHS)
         .addMBB(TailMBB);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td 
b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
index b6b64b57b1b3e..19de5a0ac4005 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
@@ -496,6 +496,22 @@ class RVInstB<bits<3> funct3, RISCVOpcode opcode, dag 
outs, dag ins,
   let Inst{6-0} = opcode.Value;
 }
 
+class RVInstBIMM<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins,
+                 string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatB> {
+  bits<12> imm12;
+  bits<5> cimm;
+  bits<5> rs1;
+  let Inst{31} = imm12{11};
+  let Inst{30-25} = imm12{9-4};
+  let Inst{24-20} = cimm;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = funct3;
+  let Inst{11-8} = imm12{3-0};
+  let Inst{7} = imm12{10};
+  let Inst{6-0} = opcode.Value;
+}
+
 class RVInstU<RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
               string argstr>
     : RVInst<outs, ins, opcodestr, argstr, [], InstFormatU> {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp 
b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index a72bc416eba0b..5b7060d9bae33 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -961,11 +961,13 @@ RISCVCC::CondCode 
RISCVInstrInfo::getCondFromBranchOpc(unsigned Opc) {
   default:
     return RISCVCC::COND_INVALID;
   case RISCV::BEQ:
+  case RISCV::BEQI:
   case RISCV::CV_BEQIMM:
   case RISCV::QC_BEQI:
   case RISCV::QC_E_BEQI:
     return RISCVCC::COND_EQ;
   case RISCV::BNE:
+  case RISCV::BNEI:
   case RISCV::QC_BNEI:
   case RISCV::QC_E_BNEI:
   case RISCV::CV_BNEIMM:
@@ -1023,16 +1025,17 @@ static void parseCondBranch(MachineInstr &LastInst, 
MachineBasicBlock *&Target,
   Cond.push_back(LastInst.getOperand(1));
 }
 
-unsigned RISCVCC::getBrCond(RISCVCC::CondCode CC, unsigned SelectOpc) {
+unsigned RISCVCC::getBrCond(const RISCVSubtarget &STI, CondCode CC,
+                            unsigned SelectOpc, bool Imm) {
   switch (SelectOpc) {
   default:
     switch (CC) {
     default:
       llvm_unreachable("Unexpected condition code!");
     case RISCVCC::COND_EQ:
-      return RISCV::BEQ;
+      return (Imm && STI.hasStdExtZibi()) ? RISCV::BEQI : RISCV::BEQ;
     case RISCVCC::COND_NE:
-      return RISCV::BNE;
+      return (Imm && STI.hasStdExtZibi()) ? RISCV::BNEI : RISCV::BNE;
     case RISCVCC::COND_LT:
       return RISCV::BLT;
     case RISCVCC::COND_GE:
@@ -1341,9 +1344,15 @@ bool RISCVInstrInfo::reverseBranchCondition(
   case RISCV::BEQ:
     Cond[0].setImm(RISCV::BNE);
     break;
+  case RISCV::BEQI:
+    Cond[0].setImm(RISCV::BNEI);
+    break;
   case RISCV::BNE:
     Cond[0].setImm(RISCV::BEQ);
     break;
+  case RISCV::BNEI:
+    Cond[0].setImm(RISCV::BEQI);
+    break;
   case RISCV::BLT:
     Cond[0].setImm(RISCV::BGE);
     break;
@@ -1506,7 +1515,7 @@ bool RISCVInstrInfo::optimizeCondBranch(MachineInstr &MI) 
const {
     return Register();
   };
 
-  unsigned NewOpc = RISCVCC::getBrCond(getOppositeBranchCondition(CC));
+  unsigned NewOpc = RISCVCC::getBrCond(STI, getOppositeBranchCondition(CC));
 
   // Might be case 1.
   // Don't change 0 to 1 since we can use x0.
@@ -1576,6 +1585,8 @@ bool RISCVInstrInfo::isBranchOffsetInRange(unsigned 
BranchOp,
   case RISCV::BGE:
   case RISCV::BLTU:
   case RISCV::BGEU:
+  case RISCV::BEQI:
+  case RISCV::BNEI:
   case RISCV::CV_BEQIMM:
   case RISCV::CV_BNEIMM:
   case RISCV::QC_BEQI:
@@ -2775,6 +2786,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr 
&MI,
         case RISCVOp::OPERAND_UIMM2_LSB0:
           Ok = isShiftedUInt<1, 1>(Imm);
           break;
+        case RISCVOp::OPERAND_UIMM5_ZIBI:
+          Ok = (isUInt<5>(Imm) && Imm != 0) || Imm == -1;
+          break;
         case RISCVOp::OPERAND_UIMM5_LSB0:
           Ok = isShiftedUInt<4, 1>(Imm);
           break;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h 
b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
index 785c8352d4a5e..060d4cbb4425e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
@@ -45,7 +45,8 @@ enum CondCode {
 };
 
 CondCode getOppositeBranchCondition(CondCode);
-unsigned getBrCond(CondCode CC, unsigned SelectOpc = 0);
+unsigned getBrCond(const RISCVSubtarget &STI, CondCode CC,
+                   unsigned SelectOpc = 0, bool Imm = false);
 
 } // end of namespace RISCVCC
 
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index e0321443ba2d4..40ea3301adccf 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2255,6 +2255,7 @@ include "RISCVInstrInfoZicbo.td"
 include "RISCVInstrInfoZicond.td"
 include "RISCVInstrInfoZicfiss.td"
 include "RISCVInstrInfoZilsd.td"
+include "RISCVInstrInfoZibi.td"
 
 // Scalar FP
 include "RISCVInstrInfoF.td"
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZibi.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfoZibi.td
new file mode 100644
index 0000000000000..745bc0800120b
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZibi.td
@@ -0,0 +1,51 @@
+//===-- RISCVInstrInfoZibi.td - 'Zibi' instructions ------*- 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 instructions for 'Zibi' (branch with imm).
+///
+//===----------------------------------------------------------------------===//
+// A 5-bit unsigned immediate representing 1-31 and -1. 00000 represents -1.
+def uimm5_zibi : RISCVOp<XLenVT>, ImmLeaf<XLenVT, [{
+    return (Imm != 0 && isUInt<5>(Imm)) || Imm == -1;
+}]> {
+  let ParserMatchClass = UImmAsmOperand<5, "Zibi">;
+  let EncoderMethod = "getImmOpValueZibi";
+  let DecoderMethod = "decodeUImmZibiOperand";
+  let MCOperandPredicate = [{
+    int64_t Imm;
+    if (!MCOp.evaluateAsConstantImm(Imm))
+      return false;
+    return (Imm >= 1 && Imm <= 31) || Imm == -1;
+  }];
+  let OperandType = "OPERAND_UIMM5_ZIBI";
+}
+
+class Branch_imm<bits<3> funct3, string opcodestr>
+    : RVInstBIMM<funct3, OPC_BRANCH, (outs),
+                 (ins GPR:$rs1, uimm5_zibi:$cimm, bare_simm13_lsb0:$imm12),
+                 opcodestr, "$rs1, $cimm, $imm12">,
+      Sched<[WriteJmp, ReadJmp]> {
+  let isBranch = 1;
+  let isTerminator = 1;
+  let hasSideEffects = 0;
+  let mayLoad = 0;
+  let mayStore = 0;
+}
+let Predicates = [HasStdExtZibi] in {
+  def BEQI : Branch_imm<0b010, "beqi">;
+  def BNEI : Branch_imm<0b011, "bnei">;
+} // Predicates = [HasStdExtZibi]
+
+let Predicates = [HasStdExtZibi] in {
+  multiclass BccImmPat<CondCode Cond, Branch_imm Inst> {
+    def : Pat<(riscv_brcc(XLenVT GPR:$rs1), uimm5_zibi:$cimm, Cond, bb:$imm12),
+              (Inst GPR:$rs1, uimm5_zibi:$cimm, bare_simm13_lsb0_bb:$imm12)>;
+  }
+  defm : BccImmPat<SETEQ, BEQI>;
+  defm : BccImmPat<SETNE, BNEI>;
+} // Predicates = [HasStdExtZibi]
\ No newline at end of file
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll 
b/llvm/test/CodeGen/RISCV/attributes.ll
index d0afea9754aa0..e3e170fcbcb10 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -173,6 +173,7 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+supm %s -o - | FileCheck 
--check-prefix=RV32SUPM %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-smctr  %s -o - | FileCheck 
--check-prefix=RV32SMCTR %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-ssctr  %s -o - | FileCheck 
--check-prefix=RV32SSCTR %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zibi %s -o - | FileCheck 
--check-prefix=RV32ZIBI %s
 
 ; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s
 ; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck 
--check-prefixes=CHECK,RV64M %s
@@ -338,6 +339,7 @@
 ; RUN: llc -mtriple=riscv64 -mattr=+sdtrig  %s -o - | FileCheck 
--check-prefix=RV64SDTRIG %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-xqccmp %s -o - | FileCheck 
--check-prefix=RV64XQCCMP %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-p %s -o - | FileCheck 
--check-prefix=RV64P %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zibi %s -o - | FileCheck 
--check-prefix=RV64ZIBI %s
 
 
 ; Tests for profile features.
@@ -528,6 +530,7 @@
 ; RV32SMCTR: .attribute 5, "rv32i2p1_smctr1p0_sscsrind1p0"
 ; RV32SSCTR: .attribute 5, "rv32i2p1_sscsrind1p0_ssctr1p0"
 ; RV32P: .at...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/146858
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to