[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