[llvm] [RISCV] Add short forward branch support for `lui`, `qc.li`, and `qc.e.li` (PR #167481)

via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 11 01:36:55 PST 2025


https://github.com/hchandel created https://github.com/llvm/llvm-project/pull/167481

None

>From d549639c3dbf778ecfb2f12e742cc68eb647176d Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Fri, 7 Nov 2025 16:49:28 +0530
Subject: [PATCH 1/3] Working changes for SFB + qc.li, qc.e.li, lui

Change-Id: Idd925d4e56081cfc0547cc48cdf5c7bf08a1b241
---
 .../Target/RISCV/RISCVExpandPseudoInsts.cpp   | 13 ++++++++-
 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp      |  3 ++
 llvm/lib/Target/RISCV/RISCVInstrInfo.td       |  6 ++--
 llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td    | 28 +++++++++++++++++++
 4 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
index b0453fc57c053..5b0b7b02f0564 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
@@ -132,6 +132,9 @@ bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
   case RISCV::PseudoCCMIN:
   case RISCV::PseudoCCMINU:
   case RISCV::PseudoCCMUL:
+  case RISCV::PseudoCCLUI:
+  case RISCV::PseudoCCQCLI:
+  case RISCV::PseudoCCQCELI:
   case RISCV::PseudoCCADDW:
   case RISCV::PseudoCCSUBW:
   case RISCV::PseudoCCSLL:
@@ -239,6 +242,9 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
     case RISCV::PseudoCCMAXU:  NewOpc = RISCV::MAXU;  break;
     case RISCV::PseudoCCMINU:  NewOpc = RISCV::MINU;  break;
     case RISCV::PseudoCCMUL:   NewOpc = RISCV::MUL;   break;
+    case RISCV::PseudoCCLUI:   NewOpc = RISCV::LUI;   break;
+    case RISCV::PseudoCCQCLI:  NewOpc = RISCV::QC_LI;   break;
+    case RISCV::PseudoCCQCELI: NewOpc = RISCV::QC_E_LI;   break;
     case RISCV::PseudoCCADDI:  NewOpc = RISCV::ADDI;  break;
     case RISCV::PseudoCCSLLI:  NewOpc = RISCV::SLLI;  break;
     case RISCV::PseudoCCSRLI:  NewOpc = RISCV::SRLI;  break;
@@ -268,7 +274,12 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
           .add(MI.getOperand(5))
           .add(MI.getOperand(6))
           .add(MI.getOperand(7));
-    } else {
+    }
+    else if(NewOpc == RISCV::LUI || NewOpc == RISCV::QC_LI || NewOpc == RISCV::QC_E_LI) {
+      BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg)
+          .add(MI.getOperand(5));
+    }
+    else {
       BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg)
           .add(MI.getOperand(5))
           .add(MI.getOperand(6));
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index b8ab70bd9e386..57a27dca90cc1 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -1704,6 +1704,9 @@ unsigned getPredicatedOpcode(unsigned Opcode) {
   case RISCV::MIN:   return RISCV::PseudoCCMIN;
   case RISCV::MINU:  return RISCV::PseudoCCMINU;
   case RISCV::MUL:   return RISCV::PseudoCCMUL;
+  case RISCV::LUI:   return RISCV::PseudoCCLUI;
+  case RISCV::QC_LI:   return RISCV::PseudoCCQCLI;
+  case RISCV::QC_E_LI:   return RISCV::PseudoCCQCELI;
 
   case RISCV::ADDI:  return RISCV::PseudoCCADDI;
   case RISCV::SLLI:  return RISCV::PseudoCCSLLI;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 9cb53fb27a2d2..a9de1dd091779 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2363,9 +2363,6 @@ include "RISCVInstrInfoZclsd.td"
 // Control Flow Integriy, this requires Zimop/Zcmop
 include "RISCVInstrInfoZicfiss.td"
 
-// Short Forward Branch
-include "RISCVInstrInfoSFB.td"
-
 //===----------------------------------------------------------------------===//
 // Vendor extensions
 //===----------------------------------------------------------------------===//
@@ -2388,3 +2385,6 @@ include "RISCVInstrInfoXSpacemiT.td"
 //===----------------------------------------------------------------------===//
 
 include "RISCVInstrGISel.td"
+
+// Short Forward Branch
+include "RISCVInstrInfoSFB.td"
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
index 494b1c9f98839..1d54216b2f2fc 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
@@ -69,6 +69,30 @@ class SFBALU_ri
   let Constraints = "$dst = $falsev";
 }
 
+class SFBLUI
+    : Pseudo<(outs GPR:$dst),
+             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
+                  uimm20_lui:$imm), []>,
+      Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
+  let hasSideEffects = 0;
+  let mayLoad = 0;
+  let mayStore = 0;
+  let Size = 8;
+  let Constraints = "$dst = $falsev";
+}
+
+class SFBQCELI
+    : Pseudo<(outs GPR:$dst),
+             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
+                  bare_simm32:$imm), []>,
+      Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
+  let hasSideEffects = 0;
+  let mayLoad = 0;
+  let mayStore = 0;
+  let Size = 10;
+  let Constraints = "$dst = $falsev";
+}
+
 class SFBShift_ri
     : Pseudo<(outs GPR:$dst),
              (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
@@ -117,6 +141,10 @@ def PseudoCCANDI : SFBALU_ri;
 def PseudoCCORI  : SFBALU_ri;
 def PseudoCCXORI : SFBALU_ri;
 
+def PseudoCCLUI : SFBLUI;
+def PseudoCCQCLI : SFBLUI;
+def PseudoCCQCELI : SFBQCELI;
+
 def PseudoCCSLLI : SFBShift_ri;
 def PseudoCCSRLI : SFBShift_ri;
 def PseudoCCSRAI : SFBShift_ri;

>From 6f58db7e67ac01a360bef4ba4c97f9c4f27527c9 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Mon, 10 Nov 2025 15:00:49 +0530
Subject: [PATCH 2/3] [RISCV] Short forward branch support for lui, qc.li,
 qc.e.li

Change-Id: I90945585893ecdbdccff472247b0d82eb97b49d4
---
 llvm/lib/Target/RISCV/RISCVInstrInfo.td       |   6 +-
 llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td    |  17 +--
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td   |  16 ++
 .../RISCV/short-forward-branch-load-imm.ll    | 139 ++++++++++++++++++
 4 files changed, 159 insertions(+), 19 deletions(-)
 create mode 100644 llvm/test/CodeGen/RISCV/short-forward-branch-load-imm.ll

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index a9de1dd091779..9cb53fb27a2d2 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2363,6 +2363,9 @@ include "RISCVInstrInfoZclsd.td"
 // Control Flow Integriy, this requires Zimop/Zcmop
 include "RISCVInstrInfoZicfiss.td"
 
+// Short Forward Branch
+include "RISCVInstrInfoSFB.td"
+
 //===----------------------------------------------------------------------===//
 // Vendor extensions
 //===----------------------------------------------------------------------===//
@@ -2385,6 +2388,3 @@ include "RISCVInstrInfoXSpacemiT.td"
 //===----------------------------------------------------------------------===//
 
 include "RISCVInstrGISel.td"
-
-// Short Forward Branch
-include "RISCVInstrInfoSFB.td"
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
index 1d54216b2f2fc..e592f56f6f58a 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
@@ -72,8 +72,7 @@ class SFBALU_ri
 class SFBLUI
     : Pseudo<(outs GPR:$dst),
              (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
-                  uimm20_lui:$imm), []>,
-      Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
+                  uimm20_lui:$imm), []> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
@@ -81,18 +80,6 @@ class SFBLUI
   let Constraints = "$dst = $falsev";
 }
 
-class SFBQCELI
-    : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
-                  bare_simm32:$imm), []>,
-      Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
-  let hasSideEffects = 0;
-  let mayLoad = 0;
-  let mayStore = 0;
-  let Size = 10;
-  let Constraints = "$dst = $falsev";
-}
-
 class SFBShift_ri
     : Pseudo<(outs GPR:$dst),
              (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
@@ -142,8 +129,6 @@ def PseudoCCORI  : SFBALU_ri;
 def PseudoCCXORI : SFBALU_ri;
 
 def PseudoCCLUI : SFBLUI;
-def PseudoCCQCLI : SFBLUI;
-def PseudoCCQCELI : SFBQCELI;
 
 def PseudoCCSLLI : SFBShift_ri;
 def PseudoCCSRLI : SFBShift_ri;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 8376da52be53e..a2c14a84254fb 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -817,6 +817,17 @@ class QCIRVInst48EJ<bits<2> func2, string opcodestr>
   let Inst{6-0} = 0b0011111;
 }
 
+class SFBQCELI
+    : Pseudo<(outs GPR:$dst),
+             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
+                  bare_simm32:$imm), []> {
+  let hasSideEffects = 0;
+  let mayLoad = 0;
+  let mayStore = 0;
+  let Size = 10;
+  let Constraints = "$dst = $falsev";
+}
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -1308,6 +1319,11 @@ def PseudoQC_E_SH : PseudoStore<"qc.e.sh">;
 def PseudoQC_E_SW : PseudoStore<"qc.e.sw">;
 } // Predicates = [HasVendorXqcilo, IsRV32]
 
+let Predicates = [HasShortForwardBranchOpt] in {
+def PseudoCCQCLI : SFBLUI;
+def PseudoCCQCELI : SFBQCELI;
+}
+
 //===----------------------------------------------------------------------===//
 // Code Gen Patterns
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/RISCV/short-forward-branch-load-imm.ll b/llvm/test/CodeGen/RISCV/short-forward-branch-load-imm.ll
new file mode 100644
index 0000000000000..114de4f4d084b
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/short-forward-branch-load-imm.ll
@@ -0,0 +1,139 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=riscv32 -mattr=+experimental-xqcili | FileCheck %s --check-prefixes=RV32I
+; RUN: llc < %s -mtriple=riscv64 | FileCheck %s --check-prefixes=RV64I
+; RUN: llc < %s -mtriple=riscv32 -mattr=+experimental-xqcili,+short-forward-branch-opt | \
+; RUN:   FileCheck %s --check-prefixes=RV32I-SFB
+; RUN: llc < %s -mtriple=riscv64 -mattr=+short-forward-branch-opt | \
+; RUN:   FileCheck %s --check-prefixes=RV64I-SFB
+
+define i32 @select_example_1(i32 %a, i32 %b, i1 zeroext %x, i32 %y) {
+; RV32I-LABEL: select_example_1:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    lui a0, 16
+; RV32I-NEXT:    bnez a2, .LBB0_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a0, a1
+; RV32I-NEXT:  .LBB0_2: # %entry
+; RV32I-NEXT:    ret
+;
+; RV64I-LABEL: select_example_1:
+; RV64I:       # %bb.0: # %entry
+; RV64I-NEXT:    lui a0, 16
+; RV64I-NEXT:    bnez a2, .LBB0_2
+; RV64I-NEXT:  # %bb.1: # %entry
+; RV64I-NEXT:    mv a0, a1
+; RV64I-NEXT:  .LBB0_2: # %entry
+; RV64I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: select_example_1:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    mv a0, a1
+; RV32I-SFB-NEXT:    beqz a2, .LBB0_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    lui a0, 16
+; RV32I-SFB-NEXT:  .LBB0_2: # %entry
+; RV32I-SFB-NEXT:    ret
+;
+; RV64I-SFB-LABEL: select_example_1:
+; RV64I-SFB:       # %bb.0: # %entry
+; RV64I-SFB-NEXT:    mv a0, a1
+; RV64I-SFB-NEXT:    beqz a2, .LBB0_2
+; RV64I-SFB-NEXT:  # %bb.1: # %entry
+; RV64I-SFB-NEXT:    lui a0, 16
+; RV64I-SFB-NEXT:  .LBB0_2: # %entry
+; RV64I-SFB-NEXT:    ret
+entry:
+  %sel = select i1 %x, i32 65536, i32 %b
+  ret i32 %sel
+}
+
+define i32 @select_example_2(i32 %a, i32 %b, i1 zeroext %x, i32 %y) {
+; RV32I-LABEL: select_example_2:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    bnez a2, .LBB1_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a0, a1
+; RV32I-NEXT:    ret
+; RV32I-NEXT:  .LBB1_2:
+; RV32I-NEXT:    qc.li a0, 65543
+; RV32I-NEXT:    ret
+;
+; RV64I-LABEL: select_example_2:
+; RV64I:       # %bb.0: # %entry
+; RV64I-NEXT:    bnez a2, .LBB1_2
+; RV64I-NEXT:  # %bb.1: # %entry
+; RV64I-NEXT:    mv a0, a1
+; RV64I-NEXT:    ret
+; RV64I-NEXT:  .LBB1_2:
+; RV64I-NEXT:    lui a0, 16
+; RV64I-NEXT:    addi a0, a0, 7
+; RV64I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: select_example_2:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    mv a0, a1
+; RV32I-SFB-NEXT:    beqz a2, .LBB1_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    qc.li a0, 65543
+; RV32I-SFB-NEXT:  .LBB1_2: # %entry
+; RV32I-SFB-NEXT:    ret
+;
+; RV64I-SFB-LABEL: select_example_2:
+; RV64I-SFB:       # %bb.0: # %entry
+; RV64I-SFB-NEXT:    mv a0, a1
+; RV64I-SFB-NEXT:    lui a1, 16
+; RV64I-SFB-NEXT:    beqz a2, .LBB1_2
+; RV64I-SFB-NEXT:  # %bb.1: # %entry
+; RV64I-SFB-NEXT:    addi a0, a1, 7
+; RV64I-SFB-NEXT:  .LBB1_2: # %entry
+; RV64I-SFB-NEXT:    ret
+entry:
+  %sel = select i1 %x, i32 65543, i32 %b
+  ret i32 %sel
+}
+
+define i32 @select_example_3(i32 %a, i32 %b, i1 zeroext %x, i32 %y) {
+; RV32I-LABEL: select_example_3:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    bnez a2, .LBB2_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a0, a1
+; RV32I-NEXT:    ret
+; RV32I-NEXT:  .LBB2_2:
+; RV32I-NEXT:    qc.e.li a0, 4198928
+; RV32I-NEXT:    ret
+;
+; RV64I-LABEL: select_example_3:
+; RV64I:       # %bb.0: # %entry
+; RV64I-NEXT:    bnez a2, .LBB2_2
+; RV64I-NEXT:  # %bb.1: # %entry
+; RV64I-NEXT:    mv a0, a1
+; RV64I-NEXT:    ret
+; RV64I-NEXT:  .LBB2_2:
+; RV64I-NEXT:    lui a0, 1025
+; RV64I-NEXT:    addi a0, a0, 528
+; RV64I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: select_example_3:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    mv a0, a1
+; RV32I-SFB-NEXT:    beqz a2, .LBB2_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    qc.e.li a0, 4198928
+; RV32I-SFB-NEXT:  .LBB2_2: # %entry
+; RV32I-SFB-NEXT:    ret
+;
+; RV64I-SFB-LABEL: select_example_3:
+; RV64I-SFB:       # %bb.0: # %entry
+; RV64I-SFB-NEXT:    mv a0, a1
+; RV64I-SFB-NEXT:    lui a1, 1025
+; RV64I-SFB-NEXT:    beqz a2, .LBB2_2
+; RV64I-SFB-NEXT:  # %bb.1: # %entry
+; RV64I-SFB-NEXT:    addi a0, a1, 528
+; RV64I-SFB-NEXT:  .LBB2_2: # %entry
+; RV64I-SFB-NEXT:    ret
+entry:
+  %sel = select i1 %x, i32 4198928, i32 %b
+  ret i32 %sel
+}
+

>From c8752686f3f5dc5b0ca8996846c066a42b819075 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Mon, 10 Nov 2025 15:27:06 +0530
Subject: [PATCH 3/3] fixup! Use separate class for qc.li to use correct imm
 type

Change-Id: I7c867003f4bcd7bbfa426ef1fbb4d16cb57a57e3
---
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index a2c14a84254fb..dbaaa8504177f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -817,6 +817,17 @@ class QCIRVInst48EJ<bits<2> func2, string opcodestr>
   let Inst{6-0} = 0b0011111;
 }
 
+class SFBQCLI
+    : Pseudo<(outs GPR:$dst),
+             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
+                  simm20_li:$imm), []> {
+  let hasSideEffects = 0;
+  let mayLoad = 0;
+  let mayStore = 0;
+  let Size = 8;
+  let Constraints = "$dst = $falsev";
+}
+
 class SFBQCELI
     : Pseudo<(outs GPR:$dst),
              (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
@@ -1320,7 +1331,7 @@ def PseudoQC_E_SW : PseudoStore<"qc.e.sw">;
 } // Predicates = [HasVendorXqcilo, IsRV32]
 
 let Predicates = [HasShortForwardBranchOpt] in {
-def PseudoCCQCLI : SFBLUI;
+def PseudoCCQCLI : SFBQCLI;
 def PseudoCCQCELI : SFBQCELI;
 }
 



More information about the llvm-commits mailing list