[clang] [llvm] [RISCV] Add Support of RISCV Zibimm Experimental Extension (PR #127463)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 17 01:45:54 PST 2025
https://github.com/BoyaoWang430 created https://github.com/llvm/llvm-project/pull/127463
Add Support of RISCV Zibimm v0.1 Experimental Extension.
>From a90aa31f9a0cb4b050dfa0eeefa499b09b4b0b71 Mon Sep 17 00:00:00 2001
From: wangboyao <wangboyao at bytedance.com>
Date: Mon, 17 Feb 2025 17:35:52 +0800
Subject: [PATCH] [RISCV] Add Support of RISCV Zibimm Experimental Extension
---
.../Driver/print-supported-extensions-riscv.c | 1 +
.../test/Preprocessor/riscv-target-features.c | 9 +
.../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 15 +
.../RISCV/Disassembler/RISCVDisassembler.cpp | 12 +
.../RISCV/GISel/RISCVInstructionSelector.cpp | 2 +-
.../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 1 +
.../RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 20 ++
llvm/lib/Target/RISCV/RISCVFeatures.td | 6 +
llvm/lib/Target/RISCV/RISCVInstrFormats.td | 16 +
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 19 +-
llvm/lib/Target/RISCV/RISCVInstrInfo.h | 2 +-
llvm/lib/Target/RISCV/RISCVInstrInfo.td | 1 +
llvm/lib/Target/RISCV/RISCVInstrInfoZibimm.td | 48 +++
llvm/test/CodeGen/RISCV/attributes.ll | 4 +
llvm/test/CodeGen/RISCV/zibimm.ll | 299 ++++++++++++++++++
llvm/test/MC/RISCV/zibimm-invalid.s | 34 ++
llvm/test/MC/RISCV/zibimm-valid.s | 63 ++++
.../TargetParser/RISCVISAInfoTest.cpp | 1 +
18 files changed, 547 insertions(+), 6 deletions(-)
create mode 100644 llvm/lib/Target/RISCV/RISCVInstrInfoZibimm.td
create mode 100644 llvm/test/CodeGen/RISCV/zibimm.ll
create mode 100644 llvm/test/MC/RISCV/zibimm-invalid.s
create mode 100644 llvm/test/MC/RISCV/zibimm-valid.s
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 49c5bfca2716f..8d04e87c12077 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -14,6 +14,7 @@
// CHECK-NEXT: b 1.0 'B' (the collection of the Zba, Zbb, Zbs extensions)
// CHECK-NEXT: v 1.0 'V' (Vector Extension for Application Processors)
// CHECK-NEXT: h 1.0 'H' (Hypervisor)
+// CHECK-NEXT: zibimm 0.1 'Zibimm' (Branch with Immediate)
// CHECK-NEXT: zic64b 1.0 'Zic64b' (Cache Block Size Is 64 Bytes)
// CHECK-NEXT: zicbom 1.0 'Zicbom' (Cache-Block Management Instructions)
// CHECK-NEXT: zicbop 1.0 'Zicbop' (Cache-Block Prefetch Instructions)
diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c
index c219771135275..0f4921a92d3cf 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -118,6 +118,7 @@
// CHECK-NOT: __riscv_zfinx {{.*$}}
// CHECK-NOT: __riscv_zhinx {{.*$}}
// CHECK-NOT: __riscv_zhinxmin {{.*$}}
+// CHECK-NOT: __riscv_zibimm {{.*$}}
// CHECK-NOT: __riscv_zic64b {{.*$}}
// CHECK-NOT: __riscv_zicbom {{.*$}}
// CHECK-NOT: __riscv_zicbop {{.*$}}
@@ -998,6 +999,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_zibimm0p1 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZIBIMM-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN: -march=rv64i_zibimm0p1 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZIBIMM-EXT %s
+// CHECK-ZIBIMM-EXT: __riscv_zibimm
+
// 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/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index ac87d72b7595c..4d3556c666b70 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -735,6 +735,17 @@ struct RISCVOperand final : public MCParsedAsmOperand {
VK == RISCVMCExpr::VK_RISCV_None;
}
+ bool isUImm5Zibimm() const {
+ if (!isImm())
+ return false;
+ int64_t Imm;
+ RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ Imm = fixImmediateForRV32(Imm, isRV64Imm());
+ return IsConstantImm && ((isUInt<5>(Imm) && Imm != 0) || Imm == -1) &&
+ VK == RISCVMCExpr::VK_RISCV_None;
+ }
+
bool isUImm5GT3() const {
if (!isImm())
return false;
@@ -1550,6 +1561,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_InvalidUImm5Zibimm:
+ 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_InvalidUImm6:
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 01648ec0cbe9e..2a35af84c64ae 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -350,6 +350,18 @@ static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
}
+template <unsigned N>
+static DecodeStatus decodeUImmZibimmOperand(MCInst &Inst, uint32_t Imm,
+ int64_t Address,
+ const MCDisassembler *Decoder) {
+ assert(isUInt<N>(Imm) && "Invalid immediate");
+ if (Imm)
+ Inst.addOperand(MCOperand::createImm(Imm));
+ else
+ Inst.addOperand(MCOperand::createImm(-1));
+ 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 62fbe55dffba1..bf38af921d074 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -789,7 +789,7 @@ 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})
+ auto Bcc = MIB.buildInstr(RISCVCC::getBrCond(STI, 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 2f4b569041a6f..2160a71fbce32 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -302,6 +302,7 @@ enum OperandType : unsigned {
OPERAND_UIMM4,
OPERAND_UIMM5,
OPERAND_UIMM5_NONZERO,
+ OPERAND_UIMM5_ZIBIMM,
OPERAND_UIMM5_GT3,
OPERAND_UIMM5_LSB0,
OPERAND_UIMM6,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 06d9cce48692a..cacf72b850dba 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -84,6 +84,10 @@ class RISCVMCCodeEmitter : public MCCodeEmitter {
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ uint64_t getImmOpValueZibimm(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;
@@ -400,6 +404,22 @@ RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
return getImmOpValue(MI, OpNo, Fixups, STI);
}
+uint64_t
+RISCVMCCodeEmitter::getImmOpValueZibimm(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+
+ if (MO.isImm()) {
+ uint64_t Res = MO.getImm();
+ if (Res >= 1 && Res <= 31)
+ return Res;
+ if (Res == (uint64_t)-1)
+ return 0;
+ }
+ return getImmOpValue(MI, OpNo, Fixups, STI);
+}
+
uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 30595119e37bf..8e1a297288445 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -77,6 +77,12 @@ def FeatureStdExtI
def FeatureStdExtE
: RISCVExtension<2, 0, "Embedded Instruction Set with 16 GPRs">;
+def FeatureStdExtZibimm
+ : RISCVExperimentalExtension<0, 1, "'Zibimm' (Branch with Immediate)">;
+def HasStdExtZibimm : Predicate<"Subtarget->hasStdExtZibimm()">,
+ AssemblerPredicate<(all_of FeatureStdExtZibimm),
+ "'Zibimm' (Branch with Immediate)">;
+
def FeatureStdExtZic64b
: RISCVExtension<1, 0, "Cache Block Size Is 64 Bytes">;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
index cea28bdce284c..9c7c64f3a72a8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
@@ -489,6 +489,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 1ec299e3c8cc0..0a8c1f3609ae6 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -923,6 +923,10 @@ static RISCVCC::CondCode getCondFromBranchOpc(unsigned Opc) {
return RISCVCC::COND_EQ;
case RISCV::CV_BNEIMM:
return RISCVCC::COND_NE;
+ case RISCV::BEQI:
+ return RISCVCC::COND_EQ;
+ case RISCV::BNEI:
+ return RISCVCC::COND_NE;
case RISCV::BEQ:
return RISCVCC::COND_EQ;
case RISCV::BNE:
@@ -953,14 +957,16 @@ static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target,
Cond.push_back(LastInst.getOperand(1));
}
-unsigned RISCVCC::getBrCond(RISCVCC::CondCode CC, bool Imm) {
+unsigned RISCVCC::getBrCond(const RISCVSubtarget& STI, RISCVCC::CondCode CC, bool Imm) {
switch (CC) {
default:
llvm_unreachable("Unknown condition code!");
case RISCVCC::COND_EQ:
- return Imm ? RISCV::CV_BEQIMM : RISCV::BEQ;
+ return Imm ? (STI.hasStdExtZibimm() ? RISCV::BEQI :
+ (STI.hasVendorXCVbi() ? RISCV::CV_BEQIMM : RISCV::BEQ)) : RISCV::BEQ;
case RISCVCC::COND_NE:
- return Imm ? RISCV::CV_BNEIMM : RISCV::BNE;
+ return Imm ? (STI.hasStdExtZibimm() ? RISCV::BNEI :
+ (STI.hasVendorXCVbi() ? RISCV::CV_BNEIMM : RISCV::BNE)) : RISCV::BNE;
case RISCVCC::COND_LT:
return RISCV::BLT;
case RISCVCC::COND_GE:
@@ -974,7 +980,7 @@ unsigned RISCVCC::getBrCond(RISCVCC::CondCode CC, bool Imm) {
const MCInstrDesc &RISCVInstrInfo::getBrCond(RISCVCC::CondCode CC,
bool Imm) const {
- return get(RISCVCC::getBrCond(CC, Imm));
+ return get(RISCVCC::getBrCond(STI, CC, Imm));
}
RISCVCC::CondCode RISCVCC::getOppositeBranchCondition(RISCVCC::CondCode CC) {
@@ -1350,6 +1356,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:
return isIntN(13, BrOffset);
@@ -2490,6 +2498,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
case RISCVOp::OPERAND_UIMM2_LSB0:
Ok = isShiftedUInt<1, 1>(Imm);
break;
+ case RISCVOp::OPERAND_UIMM5_ZIBIMM:
+ 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 ec628620d2982..c91fefa566b03 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
@@ -45,7 +45,7 @@ enum CondCode {
};
CondCode getOppositeBranchCondition(CondCode);
-unsigned getBrCond(CondCode CC, bool Imm = false);
+unsigned getBrCond(const RISCVSubtarget& STI, CondCode CC, bool Imm = false);
} // end of namespace RISCVCC
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index fde7dc89dd693..81ef41c7e74d0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2135,6 +2135,7 @@ include "RISCVInstrInfoZimop.td"
include "RISCVInstrInfoZicbo.td"
include "RISCVInstrInfoZicond.td"
include "RISCVInstrInfoZicfiss.td"
+include "RISCVInstrInfoZibimm.td"
//===----------------------------------------------------------------------===//
// Vendor extensions
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZibimm.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZibimm.td
new file mode 100644
index 0000000000000..7e813f7a73d75
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZibimm.td
@@ -0,0 +1,48 @@
+//===-- RISCVInstrInfoZvabd.td - 'Zvabd' 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 'Zibimm' (branch with imm).
+///
+//===----------------------------------------------------------------------===//
+// A 5-bit unsigned immediate representing 1-31 and -1. 00000 represents -1.
+def uimm5_zibimm : RISCVOp, ImmLeaf<XLenVT, [{
+ return (Imm != 0 && isUInt<5>(Imm)) || Imm == -1;
+}]> {
+ let ParserMatchClass = UImmAsmOperand<5, "Zibimm">;
+ let EncoderMethod = "getImmOpValueZibimm";
+ let DecoderMethod = "decodeUImmZibimmOperand<5>";
+ let MCOperandPredicate = [{
+ int64_t Imm;
+ if (!MCOp.evaluateAsConstantImm(Imm))
+ return false;
+ return (Imm >= 1 && Imm <= 31) || Imm == -1;
+ }];
+ let OperandType = "OPERAND_UIMM5_ZIBIMM";
+}
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class Branch_imm<bits<3> funct3, string opcodestr>
+ : RVInstBIMM<funct3, OPC_BRANCH, (outs),
+ (ins GPR:$rs1, uimm5_zibimm:$cimm, simm13_lsb0:$imm12),
+ opcodestr, "$rs1, $cimm, $imm12">,
+ Sched<[WriteJmp, ReadJmp]> {
+ let isBranch = 1;
+ let isTerminator = 1;
+}
+let Predicates = [HasStdExtZibimm] in {
+def BEQI : Branch_imm<0b010, "beqi">;
+def BNEI : Branch_imm<0b011, "bnei">;
+} // Predicates = [HasStdExtZibimm]
+
+let Predicates = [HasStdExtZibimm] in {
+multiclass BccImmPat<CondCode Cond, Branch_imm Inst> {
+ def : Pat<(riscv_brcc (XLenVT GPR:$rs1), uimm5_zibimm:$cimm, Cond, bb:$imm12),
+ (Inst GPR:$rs1, uimm5_zibimm:$cimm, simm13_lsb0:$imm12)>;
+}
+defm : BccImmPat<SETEQ, BEQI>;
+defm : BccImmPat<SETNE, BNEI>;
+}// Predicates = [HasStdExtZibimm]
\ No newline at end of file
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index b9d5bf0a7227c..9d6a678a59334 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -151,6 +151,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-zibimm %s -o - | FileCheck --check-prefix=RV32ZIBIMM %s
; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s
; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefixes=CHECK,RV64M %s
@@ -301,6 +302,7 @@
; RUN: llc -mtriple=riscv64 -mattr=+experimental-ssctr %s -o - | FileCheck --check-prefix=RV64SSCTR %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-sdext %s -o - | FileCheck --check-prefix=RV64SDEXT %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-sdtrig %s -o - | FileCheck --check-prefix=RV64SDTRIG %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zibimm %s -o - | FileCheck --check-prefix=RV64ZIBIMM %s
; Tests for profile features.
; RUN: llc -mtriple=riscv32 -mattr=+rvi20u32 %s -o - | FileCheck --check-prefix=RVI20U32 %s
@@ -467,6 +469,7 @@
; RV32SUPM: .attribute 5, "rv32i2p1_supm1p0"
; RV32SMCTR: .attribute 5, "rv32i2p1_smctr1p0_sscsrind1p0"
; RV32SSCTR: .attribute 5, "rv32i2p1_sscsrind1p0_ssctr1p0"
+; RV32ZIBIMM: .attribute 5, "rv32i2p1_zibimm0p1"
; RV64M: .attribute 5, "rv64i2p1_m2p0_zmmul1p0"
; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0"
@@ -615,6 +618,7 @@
; RV64SSCTR: .attribute 5, "rv64i2p1_sscsrind1p0_ssctr1p0"
; RV64SDEXT: .attribute 5, "rv64i2p1_sdext1p0"
; RV64SDTRIG: .attribute 5, "rv64i2p1_sdtrig1p0"
+; RV64ZIBIMM: .attribute 5, "rv64i2p1_zibimm0p1"
; RVI20U32: .attribute 5, "rv32i2p1"
; RVI20U64: .attribute 5, "rv64i2p1"
diff --git a/llvm/test/CodeGen/RISCV/zibimm.ll b/llvm/test/CodeGen/RISCV/zibimm.ll
new file mode 100644
index 0000000000000..d0cf335bc2a36
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/zibimm.ll
@@ -0,0 +1,299 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zibimm -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV32I-ZIBIMM %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zibimm -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I-ZIBIMM %s
+
+define void @test_bne_neg(ptr %b) nounwind {
+; RV32I-ZIBIMM-LABEL: test_bne_neg:
+; RV32I-ZIBIMM: # %bb.0:
+; RV32I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV32I-ZIBIMM-NEXT: bnei a1, -1, .LBB0_2
+; RV32I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV32I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV32I-ZIBIMM-NEXT: .LBB0_2: # %end
+; RV32I-ZIBIMM-NEXT: ret
+;
+; RV64I-ZIBIMM-LABEL: test_bne_neg:
+; RV64I-ZIBIMM: # %bb.0:
+; RV64I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV64I-ZIBIMM-NEXT: bnei a1, -1, .LBB0_2
+; RV64I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV64I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV64I-ZIBIMM-NEXT: .LBB0_2: # %end
+; RV64I-ZIBIMM-NEXT: ret
+ %val1 = load volatile i32, ptr %b
+ %tst1 = icmp ne i32 %val1, -1
+ br i1 %tst1, label %end, label %test2, !prof !0
+test2:
+ %val2 = load volatile i32, ptr %b
+ br label %end
+end:
+ ret void
+}
+!0 = !{!"branch_weights", i32 1, i32 99}
+
+define void @test_beq_neg(ptr %b) nounwind {
+; RV32I-ZIBIMM-LABEL: test_beq_neg:
+; RV32I-ZIBIMM: # %bb.0:
+; RV32I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV32I-ZIBIMM-NEXT: beqi a1, -1, .LBB1_2
+; RV32I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV32I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV32I-ZIBIMM-NEXT: .LBB1_2: # %end
+; RV32I-ZIBIMM-NEXT: ret
+;
+; RV64I-ZIBIMM-LABEL: test_beq_neg:
+; RV64I-ZIBIMM: # %bb.0:
+; RV64I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV64I-ZIBIMM-NEXT: beqi a1, -1, .LBB1_2
+; RV64I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV64I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV64I-ZIBIMM-NEXT: .LBB1_2: # %end
+; RV64I-ZIBIMM-NEXT: ret
+ %val1 = load volatile i32, ptr %b
+ %tst1 = icmp eq i32 %val1, -1
+ br i1 %tst1, label %end, label %test2, !prof !1
+test2:
+ %val2 = load volatile i32, ptr %b
+ br label %end
+end:
+ ret void
+}
+!1 = !{!"branch_weights", i32 1, i32 99}
+
+define void @test_bne_zero(ptr %b) nounwind {
+; RV32I-ZIBIMM-LABEL: test_bne_zero:
+; RV32I-ZIBIMM: # %bb.0:
+; RV32I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV32I-ZIBIMM-NEXT: bnez a1, .LBB2_2
+; RV32I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV32I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV32I-ZIBIMM-NEXT: .LBB2_2: # %end
+; RV32I-ZIBIMM-NEXT: ret
+;
+; RV64I-ZIBIMM-LABEL: test_bne_zero:
+; RV64I-ZIBIMM: # %bb.0:
+; RV64I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV64I-ZIBIMM-NEXT: bnez a1, .LBB2_2
+; RV64I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV64I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV64I-ZIBIMM-NEXT: .LBB2_2: # %end
+; RV64I-ZIBIMM-NEXT: ret
+ %val1 = load volatile i32, ptr %b
+ %tst1 = icmp ne i32 %val1, 0
+ br i1 %tst1, label %end, label %test2, !prof !2
+test2:
+ %val2 = load volatile i32, ptr %b
+ br label %end
+end:
+ ret void
+}
+!2 = !{!"branch_weights", i32 1, i32 99}
+
+define void @test_beq_zero(ptr %b) nounwind {
+; RV32I-ZIBIMM-LABEL: test_beq_zero:
+; RV32I-ZIBIMM: # %bb.0:
+; RV32I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV32I-ZIBIMM-NEXT: beqz a1, .LBB3_2
+; RV32I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV32I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV32I-ZIBIMM-NEXT: .LBB3_2: # %end
+; RV32I-ZIBIMM-NEXT: ret
+;
+; RV64I-ZIBIMM-LABEL: test_beq_zero:
+; RV64I-ZIBIMM: # %bb.0:
+; RV64I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV64I-ZIBIMM-NEXT: beqz a1, .LBB3_2
+; RV64I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV64I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV64I-ZIBIMM-NEXT: .LBB3_2: # %end
+; RV64I-ZIBIMM-NEXT: ret
+ %val1 = load volatile i32, ptr %b
+ %tst1 = icmp eq i32 %val1, 0
+ br i1 %tst1, label %end, label %test2, !prof !3
+test2:
+ %val2 = load volatile i32, ptr %b
+ br label %end
+end:
+ ret void
+}
+!3 = !{!"branch_weights", i32 1, i32 99}
+
+define void @test_bne_1(ptr %b) nounwind {
+; RV32I-ZIBIMM-LABEL: test_bne_1:
+; RV32I-ZIBIMM: # %bb.0:
+; RV32I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV32I-ZIBIMM-NEXT: bnei a1, 1, .LBB4_2
+; RV32I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV32I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV32I-ZIBIMM-NEXT: .LBB4_2: # %end
+; RV32I-ZIBIMM-NEXT: ret
+;
+; RV64I-ZIBIMM-LABEL: test_bne_1:
+; RV64I-ZIBIMM: # %bb.0:
+; RV64I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV64I-ZIBIMM-NEXT: bnei a1, 1, .LBB4_2
+; RV64I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV64I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV64I-ZIBIMM-NEXT: .LBB4_2: # %end
+; RV64I-ZIBIMM-NEXT: ret
+ %val1 = load volatile i32, ptr %b
+ %tst1 = icmp ne i32 %val1, 1
+ br i1 %tst1, label %end, label %test2, !prof !4
+test2:
+ %val2 = load volatile i32, ptr %b
+ br label %end
+end:
+ ret void
+}
+!4 = !{!"branch_weights", i32 1, i32 99}
+
+define void @test_beq_1(ptr %b) nounwind {
+; RV32I-ZIBIMM-LABEL: test_beq_1:
+; RV32I-ZIBIMM: # %bb.0:
+; RV32I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV32I-ZIBIMM-NEXT: beqi a1, 1, .LBB5_2
+; RV32I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV32I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV32I-ZIBIMM-NEXT: .LBB5_2: # %end
+; RV32I-ZIBIMM-NEXT: ret
+;
+; RV64I-ZIBIMM-LABEL: test_beq_1:
+; RV64I-ZIBIMM: # %bb.0:
+; RV64I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV64I-ZIBIMM-NEXT: beqi a1, 1, .LBB5_2
+; RV64I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV64I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV64I-ZIBIMM-NEXT: .LBB5_2: # %end
+; RV64I-ZIBIMM-NEXT: ret
+ %val1 = load volatile i32, ptr %b
+ %tst1 = icmp eq i32 %val1, 1
+ br i1 %tst1, label %end, label %test2, !prof !5
+test2:
+ %val2 = load volatile i32, ptr %b
+ br label %end
+end:
+ ret void
+}
+!5 = !{!"branch_weights", i32 1, i32 99}
+
+define void @test_bne_31(ptr %b) nounwind {
+; RV32I-ZIBIMM-LABEL: test_bne_31:
+; RV32I-ZIBIMM: # %bb.0:
+; RV32I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV32I-ZIBIMM-NEXT: bnei a1, 31, .LBB6_2
+; RV32I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV32I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV32I-ZIBIMM-NEXT: .LBB6_2: # %end
+; RV32I-ZIBIMM-NEXT: ret
+;
+; RV64I-ZIBIMM-LABEL: test_bne_31:
+; RV64I-ZIBIMM: # %bb.0:
+; RV64I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV64I-ZIBIMM-NEXT: bnei a1, 31, .LBB6_2
+; RV64I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV64I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV64I-ZIBIMM-NEXT: .LBB6_2: # %end
+; RV64I-ZIBIMM-NEXT: ret
+ %val1 = load volatile i32, ptr %b
+ %tst1 = icmp ne i32 %val1, 31
+ br i1 %tst1, label %end, label %test2, !prof !6
+test2:
+ %val2 = load volatile i32, ptr %b
+ br label %end
+end:
+ ret void
+}
+!6 = !{!"branch_weights", i32 1, i32 99}
+
+define void @test_beq_31(ptr %b) nounwind {
+; RV32I-ZIBIMM-LABEL: test_beq_31:
+; RV32I-ZIBIMM: # %bb.0:
+; RV32I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV32I-ZIBIMM-NEXT: beqi a1, 1, .LBB7_2
+; RV32I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV32I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV32I-ZIBIMM-NEXT: .LBB7_2: # %end
+; RV32I-ZIBIMM-NEXT: ret
+;
+; RV64I-ZIBIMM-LABEL: test_beq_31:
+; RV64I-ZIBIMM: # %bb.0:
+; RV64I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV64I-ZIBIMM-NEXT: beqi a1, 1, .LBB7_2
+; RV64I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV64I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV64I-ZIBIMM-NEXT: .LBB7_2: # %end
+; RV64I-ZIBIMM-NEXT: ret
+ %val1 = load volatile i32, ptr %b
+ %tst1 = icmp eq i32 %val1, 1
+ br i1 %tst1, label %end, label %test2, !prof !7
+test2:
+ %val2 = load volatile i32, ptr %b
+ br label %end
+end:
+ ret void
+}
+!7 = !{!"branch_weights", i32 1, i32 99}
+
+define void @test_bne_32(ptr %b) nounwind {
+; RV32I-ZIBIMM-LABEL: test_bne_32:
+; RV32I-ZIBIMM: # %bb.0:
+; RV32I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV32I-ZIBIMM-NEXT: li a2, 32
+; RV32I-ZIBIMM-NEXT: bne a1, a2, .LBB8_2
+; RV32I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV32I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV32I-ZIBIMM-NEXT: .LBB8_2: # %end
+; RV32I-ZIBIMM-NEXT: ret
+;
+; RV64I-ZIBIMM-LABEL: test_bne_32:
+; RV64I-ZIBIMM: # %bb.0:
+; RV64I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV64I-ZIBIMM-NEXT: li a2, 32
+; RV64I-ZIBIMM-NEXT: bne a1, a2, .LBB8_2
+; RV64I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV64I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV64I-ZIBIMM-NEXT: .LBB8_2: # %end
+; RV64I-ZIBIMM-NEXT: ret
+ %val1 = load volatile i32, ptr %b
+ %tst1 = icmp ne i32 %val1, 32
+ br i1 %tst1, label %end, label %test2, !prof !8
+test2:
+ %val2 = load volatile i32, ptr %b
+ br label %end
+end:
+ ret void
+}
+!8 = !{!"branch_weights", i32 1, i32 99}
+
+define void @test_beq_32(ptr %b) nounwind {
+; RV32I-ZIBIMM-LABEL: test_beq_32:
+; RV32I-ZIBIMM: # %bb.0:
+; RV32I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV32I-ZIBIMM-NEXT: li a2, 32
+; RV32I-ZIBIMM-NEXT: beq a1, a2, .LBB9_2
+; RV32I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV32I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV32I-ZIBIMM-NEXT: .LBB9_2: # %end
+; RV32I-ZIBIMM-NEXT: ret
+;
+; RV64I-ZIBIMM-LABEL: test_beq_32:
+; RV64I-ZIBIMM: # %bb.0:
+; RV64I-ZIBIMM-NEXT: lw a1, 0(a0)
+; RV64I-ZIBIMM-NEXT: li a2, 32
+; RV64I-ZIBIMM-NEXT: beq a1, a2, .LBB9_2
+; RV64I-ZIBIMM-NEXT: # %bb.1: # %test2
+; RV64I-ZIBIMM-NEXT: lw zero, 0(a0)
+; RV64I-ZIBIMM-NEXT: .LBB9_2: # %end
+; RV64I-ZIBIMM-NEXT: ret
+ %val1 = load volatile i32, ptr %b
+ %tst1 = icmp eq i32 %val1, 32
+ br i1 %tst1, label %end, label %test2, !prof !9
+test2:
+ %val2 = load volatile i32, ptr %b
+ br label %end
+end:
+ ret void
+}
+!9 = !{!"branch_weights", i32 1, i32 99}
diff --git a/llvm/test/MC/RISCV/zibimm-invalid.s b/llvm/test/MC/RISCV/zibimm-invalid.s
new file mode 100644
index 0000000000000..120190a1f5411
--- /dev/null
+++ b/llvm/test/MC/RISCV/zibimm-invalid.s
@@ -0,0 +1,34 @@
+# RUN: not llvm-mc -triple=riscv32 --mattr=+experimental-zibimm %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-zibimm %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+beqi a0, 0x0, 0x400
+# CHECK-ERROR: [[@LINE-1]]:10: error: immediate must be non-zero in the range [-1, 31]
+# CHECK-ERROR-LABEL: beqi a0, 0x0, 0x400
+beqi a0, 0x21, 0x400
+# CHECK-ERROR: [[@LINE-1]]:10: error: immediate must be non-zero in the range [-1, 31]
+# CHECK-ERROR-LABEL: beqi a0, 0x21, 0x400
+beqi a2, 0x10, -0x1f000
+# CHECK-ERROR: [[@LINE-1]]:16: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+# CHECK-ERROR-LABEL: beqi a2, 0x10, -0x1f000
+beqi a2, 0x10, 0x1000
+# CHECK-ERROR: [[@LINE-1]]:16: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+# CHECK-ERROR-LABEL: beqi a2, 0x10, 0x1000
+beqi a2, 0x10, 0x111
+# CHECK-ERROR: [[@LINE-1]]:16: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+# CHECK-ERROR-LABEL: beqi a2, 0x10, 0x111
+bnei a0, 0x0, 0x400
+# CHECK-ERROR: [[@LINE-1]]:10: error: immediate must be non-zero in the range [-1, 31]
+# CHECK-ERROR-LABEL: bnei a0, 0x0, 0x400
+bnei a0, 0x21, 0x400
+# CHECK-ERROR: [[@LINE-1]]:10: error: immediate must be non-zero in the range [-1, 31]
+# CHECK-ERROR-LABEL: bnei a0, 0x21, 0x400
+bnei a2, 0x10, -0x1f000
+# CHECK-ERROR: [[@LINE-1]]:16: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+# CHECK-ERROR-LABEL: bnei a2, 0x10, -0x1f000
+bnei a2, 0x10, 0x1000
+# CHECK-ERROR: [[@LINE-1]]:16: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+# CHECK-ERROR-LABEL: bnei a2, 0x10, 0x1000
+bnei a2, 0x10, 0x111
+# CHECK-ERROR: [[@LINE-1]]:16: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+# CHECK-ERROR-LABEL: bnei a2, 0x10, 0x111
\ No newline at end of file
diff --git a/llvm/test/MC/RISCV/zibimm-valid.s b/llvm/test/MC/RISCV/zibimm-valid.s
new file mode 100644
index 0000000000000..e3baba6efa8a0
--- /dev/null
+++ b/llvm/test/MC/RISCV/zibimm-valid.s
@@ -0,0 +1,63 @@
+# RUN: llvm-mc -triple=riscv32 -show-encoding --mattr=+experimental-zibimm %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-ASM
+# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-zibimm %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-ASM
+# RUN: not llvm-mc -triple=riscv32 -show-encoding %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: not llvm-mc -triple=riscv64 -show-encoding %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+experimental-zibimm %s \
+# RUN: | llvm-objdump -d --mattr=+experimental-zibimm --no-print-imm-hex - \
+# RUN: | FileCheck %s --check-prefix=CHECK-OBJ
+# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+experimental-zibimm %s \
+# RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+experimental-zibimm %s \
+# RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+beqi a0, 1, 1024
+# CHECK-OBJ: beqi a0, 1, 0x400
+# CHECK-ASM: beqi a0, 1, 1024
+# CHECK-ENCODING: [0x63,0x20,0x15,0x40]
+# CHECK-ERROR: instruction requires the following: 'Zibimm' (Branch with Immediate){{$}}
+# CHECK-UNKNOWN: 40152063 <unknown>
+beqi a5, -1, -1024
+# CHECK-OBJ: beqi a5, -1, 0xfffffc04
+# CHECK-ASM: beqi a5, -1, -1024
+# CHECK-ENCODING: [0xe3,0xa0,0x07,0xc0]
+# CHECK-ERROR: instruction requires the following: 'Zibimm' (Branch with Immediate){{$}}
+# CHECK-UNKNOWN: c007a0e3 <unknown>
+beqi s0, 22, 0xffe
+# CHECK-OBJ: beqi s0, 22, 0x1006
+# CHECK-ASM: beqi s0, 22, 4094
+# CHECK-ENCODING: [0xe3,0x2f,0x64,0x7f]
+# CHECK-ERROR: instruction requires the following: 'Zibimm' (Branch with Immediate){{$}}
+# CHECK-UNKNOWN: 7f642fe3 <unknown>
+beqi s1, 11, -4096
+# CHECK-OBJ: beqi s1, 11, 0xfffff00c
+# CHECK-ASM: beqi s1, 11, -4096
+# CHECK-ENCODING: [0x63,0xa0,0xb4,0x80]
+# CHECK-ERROR: instruction requires the following: 'Zibimm' (Branch with Immediate){{$}}
+# CHECK-UNKNOWN: 80b4a063 <unknown>
+bnei a0, 1, 1024
+# CHECK-OBJ: bnei a0, 1, 0x410
+# CHECK-ASM: bnei a0, 1, 1024
+# CHECK-ENCODING: [0x63,0x30,0x15,0x40]
+# CHECK-ERROR: instruction requires the following: 'Zibimm' (Branch with Immediate){{$}}
+# CHECK-UNKNOWN: 40153063 <unknown>
+bnei a5, -1, -1024
+# CHECK-OBJ: bnei a5, -1, 0xfffffc14
+# CHECK-ASM: bnei a5, -1, -1024
+# CHECK-ENCODING: [0xe3,0xb0,0x07,0xc0]
+# CHECK-ERROR: instruction requires the following: 'Zibimm' (Branch with Immediate){{$}}
+# CHECK-UNKNOWN: c007b0e3 <unknown>
+bnei s0, 22, 0xffe
+# CHECK-OBJ: bnei s0, 22, 0x1016
+# CHECK-ASM: bnei s0, 22, 4094
+# CHECK-ENCODING: [0xe3,0x3f,0x64,0x7f]
+# CHECK-ERROR: instruction requires the following: 'Zibimm' (Branch with Immediate){{$}}
+# CHECK-UNKNOWN: 7f643fe3 <unknown>
+bnei s1, 11, -4096
+# CHECK-OBJ: bnei s1, 11, 0xfffff01c
+# CHECK-ASM: bnei s1, 11, -4096
+# CHECK-ENCODING: [0x63,0xb0,0xb4,0x80]
+# CHECK-ERROR: instruction requires the following: 'Zibimm' (Branch with Immediate){{$}}
+# CHECK-UNKNOWN: 80b4b063 <unknown>
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 563f587d9d1c0..9f29a362ec32c 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1109,6 +1109,7 @@ R"(All available -march extensions for RISC-V
Experimental extensions
p 0.14
+ zibimm 0.1
zicfilp 1.0 This is a long dummy description
zicfiss 1.0
zalasr 0.1
More information about the llvm-commits
mailing list