[llvm] [RISCV] Add (BSETI x0, 11) to isLoadImm for optimizeCondBranch (PR #180820)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 10 11:54:08 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Craig Topper (topperc)
<details>
<summary>Changes</summary>
optimizeCondBranch is looking for immediates that are 1 apart to rewrite the branch by sharing a constant. BSETI x0, 11 can be used to produce 2048 which is one more than the largest positive constant produced by addi.
---
Full diff: https://github.com/llvm/llvm-project/pull/180820.diff
2 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.cpp (+11-3)
- (modified) llvm/test/CodeGen/RISCV/branch-opt.ll (+60-2)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 2156d1919ddbe..ec4614966876f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -1591,13 +1591,21 @@ bool RISCVInstrInfo::reverseBranchCondition(
}
// Return true if the instruction is a load immediate instruction (i.e.
-// ADDI x0, imm).
+// (ADDI x0, imm) or (BSETI x0, imm)).
static bool isLoadImm(const MachineInstr *MI, int64_t &Imm) {
if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() &&
MI->getOperand(1).getReg() == RISCV::X0) {
Imm = MI->getOperand(2).getImm();
return true;
}
+ // BSETI can be used to create power of 2 constants. Only 2048 is currently
+ // interesting because it is 1 more than the maximum ADDI constant.
+ if (MI->getOpcode() == RISCV::BSETI && MI->getOperand(1).isReg() &&
+ MI->getOperand(1).getReg() == RISCV::X0 &&
+ MI->getOperand(2).getImm() == 11) {
+ Imm = 2048;
+ return true;
+ }
return false;
}
@@ -1702,7 +1710,7 @@ bool RISCVInstrInfo::optimizeCondBranch(MachineInstr &MI) const {
// return that.
if (isFromLoadImm(MRI, LHS, C0) && C0 != 0 && LHS.getReg().isVirtual() &&
MRI.hasOneUse(LHS.getReg()) && (IsSigned || C0 != -1)) {
- assert(isInt<12>(C0) && "Unexpected immediate");
+ assert((isInt<12>(C0) || C0 == 2048) && "Unexpected immediate");
if (Register RegZ = searchConst(C0 + 1)) {
BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpc))
.add(RHS)
@@ -1723,7 +1731,7 @@ bool RISCVInstrInfo::optimizeCondBranch(MachineInstr &MI) const {
// return that.
if (isFromLoadImm(MRI, RHS, C0) && C0 != 0 && RHS.getReg().isVirtual() &&
MRI.hasOneUse(RHS.getReg())) {
- assert(isInt<12>(C0) && "Unexpected immediate");
+ assert((isInt<12>(C0) || C0 == 2048) && "Unexpected immediate");
if (Register RegZ = searchConst(C0 - 1)) {
BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpc))
.addReg(RegZ)
diff --git a/llvm/test/CodeGen/RISCV/branch-opt.ll b/llvm/test/CodeGen/RISCV/branch-opt.ll
index e4912bbf861a2..1134b1798b97d 100644
--- a/llvm/test/CodeGen/RISCV/branch-opt.ll
+++ b/llvm/test/CodeGen/RISCV/branch-opt.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
-; RUN: llc -mtriple=riscv32 -O2 -verify-machineinstrs < %s | FileCheck %s
-; RUN: llc -mtriple=riscv64 -O2 -verify-machineinstrs < %s | FileCheck %s
+; RUN: llc -mtriple=riscv32 -mattr=+zbs -O2 -verify-machineinstrs < %s | FileCheck %s
+; RUN: llc -mtriple=riscv64 -mattr=+zbs -O2 -verify-machineinstrs < %s | FileCheck %s
define void @u_case1_a(ptr %a, i32 signext %b, ptr %c, ptr %d) {
; CHECK-LABEL: u_case1_a:
@@ -117,3 +117,61 @@ block2: ; preds = %0
end_block: ; preds = %block2, %block1
ret void
}
+
+define void @bset_case1_a(ptr %a, i32 signext %b, ptr %c, ptr %d) {
+; CHECK-LABEL: bset_case1_a:
+; CHECK: # %bb.0:
+; CHECK-NEXT: bseti a4, zero, 11
+; CHECK-NEXT: sw a4, 0(a0)
+; CHECK-NEXT: bgeu a1, a4, .LBB4_2
+; CHECK-NEXT: # %bb.1: # %block1
+; CHECK-NEXT: sw a1, 0(a2)
+; CHECK-NEXT: ret
+; CHECK-NEXT: .LBB4_2: # %block2
+; CHECK-NEXT: li a0, 87
+; CHECK-NEXT: sw a0, 0(a3)
+; CHECK-NEXT: ret
+ store i32 2048, ptr %a
+ %p = icmp ule i32 %b, 2047
+ br i1 %p, label %block1, label %block2
+
+block1: ; preds = %0
+ store i32 %b, ptr %c
+ br label %end_block
+
+block2: ; preds = %0
+ store i32 87, ptr %d
+ br label %end_block
+
+end_block: ; preds = %block2, %block1
+ ret void
+}
+
+define void @bset_case2_a(ptr %a, i32 signext %b, ptr %c, ptr %d) {
+; CHECK-LABEL: bset_case2_a:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a4, 2047
+; CHECK-NEXT: sw a4, 0(a0)
+; CHECK-NEXT: bge a4, a1, .LBB5_2
+; CHECK-NEXT: # %bb.1: # %block1
+; CHECK-NEXT: sw a1, 0(a2)
+; CHECK-NEXT: ret
+; CHECK-NEXT: .LBB5_2: # %block2
+; CHECK-NEXT: li a0, 87
+; CHECK-NEXT: sw a0, 0(a3)
+; CHECK-NEXT: ret
+ store i32 2047, ptr %a
+ %p = icmp sge i32 %b, 2048
+ br i1 %p, label %block1, label %block2
+
+block1: ; preds = %0
+ store i32 %b, ptr %c
+ br label %end_block
+
+block2: ; preds = %0
+ store i32 87, ptr %d
+ br label %end_block
+
+end_block: ; preds = %block2, %block1
+ ret void
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/180820
More information about the llvm-commits
mailing list