[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