[llvm] [RISCV] Add nds.bfos and nds.bfoz for the short forward branch optimization. (PR #145836)
Jim Lin via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 25 22:34:02 PDT 2025
https://github.com/tclin914 created https://github.com/llvm/llvm-project/pull/145836
This adds nds.bfos and nds.bfoz, which are also supported by Andes
45-series CPUs for short forward branch optimization.
>From eed01b5b31bb9da6614b177e247696bc20932e9a Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Thu, 26 Jun 2025 10:02:14 +0800
Subject: [PATCH 1/2] [RISCV] Pre-commit test
---
.../CodeGen/RISCV/short-forward-branch-opt.ll | 168 ++++++++++++++++--
1 file changed, 155 insertions(+), 13 deletions(-)
diff --git a/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll b/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll
index 13c43a3875a08..0b32f19147796 100644
--- a/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll
+++ b/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll
@@ -2,7 +2,9 @@
; RUN: llc -mtriple=riscv64 -mattr=+c,+zbb -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=NOSFB %s
; RUN: llc -mtriple=riscv64 -mcpu=sifive-u74 -mattr=+zbb -verify-machineinstrs < %s \
-; RUN: | FileCheck -check-prefixes=SFB,NOZICOND,RV64SFB %s
+; RUN: | FileCheck -check-prefixes=SFB,NOZICOND,RV64SFB,RV64SFBSIFIVEU74 %s
+; RUN: llc -mtriple=riscv64 -mcpu=andes-ax45 -mattr=+zbb -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=SFB,NOZICOND,RV64SFB,RV64SFBANDESAX45 %s
; RUN: llc -mtriple=riscv64 -mcpu=sifive-u74 -mattr=+zicond,+zbb \
; RUN: -verify-machineinstrs < %s | FileCheck -check-prefixes=SFB,ZICOND %s
; RUN: llc -mtriple=riscv32 -mcpu=sifive-e76 -mattr=+zbb -verify-machineinstrs < %s \
@@ -67,18 +69,31 @@ define signext i32 @test3(i32 signext %v, i32 signext %w, i32 signext %x, i32 si
; NOSFB-NEXT: addw a0, a1, a2
; NOSFB-NEXT: ret
;
-; RV64SFB-LABEL: test3:
-; RV64SFB: # %bb.0:
-; RV64SFB-NEXT: beqz a4, .LBB2_2
-; RV64SFB-NEXT: # %bb.1:
-; RV64SFB-NEXT: mv a2, a3
-; RV64SFB-NEXT: .LBB2_2:
-; RV64SFB-NEXT: bnez a4, .LBB2_4
-; RV64SFB-NEXT: # %bb.3:
-; RV64SFB-NEXT: mv a0, a1
-; RV64SFB-NEXT: .LBB2_4:
-; RV64SFB-NEXT: addw a0, a0, a2
-; RV64SFB-NEXT: ret
+; RV64SFBSIFIVEU74-LABEL: test3:
+; RV64SFBSIFIVEU74: # %bb.0:
+; RV64SFBSIFIVEU74-NEXT: beqz a4, .LBB2_2
+; RV64SFBSIFIVEU74-NEXT: # %bb.1:
+; RV64SFBSIFIVEU74-NEXT: mv a2, a3
+; RV64SFBSIFIVEU74-NEXT: .LBB2_2:
+; RV64SFBSIFIVEU74-NEXT: bnez a4, .LBB2_4
+; RV64SFBSIFIVEU74-NEXT: # %bb.3:
+; RV64SFBSIFIVEU74-NEXT: mv a0, a1
+; RV64SFBSIFIVEU74-NEXT: .LBB2_4:
+; RV64SFBSIFIVEU74-NEXT: addw a0, a0, a2
+; RV64SFBSIFIVEU74-NEXT: ret
+;
+; RV64SFBANDESAX45-LABEL: test3:
+; RV64SFBANDESAX45: # %bb.0:
+; RV64SFBANDESAX45-NEXT: bnez a4, .LBB2_2
+; RV64SFBANDESAX45-NEXT: # %bb.1:
+; RV64SFBANDESAX45-NEXT: mv a0, a1
+; RV64SFBANDESAX45-NEXT: .LBB2_2:
+; RV64SFBANDESAX45-NEXT: beqz a4, .LBB2_4
+; RV64SFBANDESAX45-NEXT: # %bb.3:
+; RV64SFBANDESAX45-NEXT: mv a2, a3
+; RV64SFBANDESAX45-NEXT: .LBB2_4:
+; RV64SFBANDESAX45-NEXT: addw a0, a0, a2
+; RV64SFBANDESAX45-NEXT: ret
;
; ZICOND-LABEL: test3:
; ZICOND: # %bb.0:
@@ -1692,3 +1707,130 @@ entry:
%2 = select i1 %cond, i64 %C, i64 %1
ret i64 %2
}
+
+define i64 @select_bfoz(i64 %A, i64 %B, i1 zeroext %cond) {
+; NOSFB-LABEL: select_bfoz:
+; NOSFB: # %bb.0: # %entry
+; NOSFB-NEXT: bnez a2, .LBB39_2
+; NOSFB-NEXT: # %bb.1: # %entry
+; NOSFB-NEXT: slli a0, a0, 38
+; NOSFB-NEXT: srli a1, a0, 61
+; NOSFB-NEXT: .LBB39_2: # %entry
+; NOSFB-NEXT: mv a0, a1
+; NOSFB-NEXT: ret
+;
+; RV64SFBSIFIVEU74-LABEL: select_bfoz:
+; RV64SFBSIFIVEU74: # %bb.0: # %entry
+; RV64SFBSIFIVEU74-NEXT: slli a0, a0, 38
+; RV64SFBSIFIVEU74-NEXT: bnez a2, .LBB39_2
+; RV64SFBSIFIVEU74-NEXT: # %bb.1: # %entry
+; RV64SFBSIFIVEU74-NEXT: srli a1, a0, 61
+; RV64SFBSIFIVEU74-NEXT: .LBB39_2: # %entry
+; RV64SFBSIFIVEU74-NEXT: mv a0, a1
+; RV64SFBSIFIVEU74-NEXT: ret
+;
+; RV64SFBANDESAX45-LABEL: select_bfoz:
+; RV64SFBANDESAX45: # %bb.0: # %entry
+; RV64SFBANDESAX45-NEXT: nds.bfoz a0, a0, 25, 23
+; RV64SFBANDESAX45-NEXT: beqz a2, .LBB39_2
+; RV64SFBANDESAX45-NEXT: # %bb.1: # %entry
+; RV64SFBANDESAX45-NEXT: mv a0, a1
+; RV64SFBANDESAX45-NEXT: .LBB39_2: # %entry
+; RV64SFBANDESAX45-NEXT: ret
+;
+; ZICOND-LABEL: select_bfoz:
+; ZICOND: # %bb.0: # %entry
+; ZICOND-NEXT: slli a0, a0, 38
+; ZICOND-NEXT: bnez a2, .LBB39_2
+; ZICOND-NEXT: # %bb.1: # %entry
+; ZICOND-NEXT: srli a1, a0, 61
+; ZICOND-NEXT: .LBB39_2: # %entry
+; ZICOND-NEXT: mv a0, a1
+; ZICOND-NEXT: ret
+;
+; RV32SFB-LABEL: select_bfoz:
+; RV32SFB: # %bb.0: # %entry
+; RV32SFB-NEXT: slli a0, a0, 6
+; RV32SFB-NEXT: mv a1, a3
+; RV32SFB-NEXT: bnez a4, .LBB39_2
+; RV32SFB-NEXT: # %bb.1: # %entry
+; RV32SFB-NEXT: srli a2, a0, 29
+; RV32SFB-NEXT: .LBB39_2: # %entry
+; RV32SFB-NEXT: bnez a4, .LBB39_4
+; RV32SFB-NEXT: # %bb.3: # %entry
+; RV32SFB-NEXT: li a1, 0
+; RV32SFB-NEXT: .LBB39_4: # %entry
+; RV32SFB-NEXT: mv a0, a2
+; RV32SFB-NEXT: ret
+entry:
+ %0 = lshr i64 %A, 23
+ %1 = and i64 %0, 7
+ %2 = select i1 %cond, i64 %B, i64 %1
+ ret i64 %2
+}
+
+define i64 @select_bfos(i64 %A, i64 %B, i1 zeroext %cond) {
+; NOSFB-LABEL: select_bfos:
+; NOSFB: # %bb.0: # %entry
+; NOSFB-NEXT: bnez a2, .LBB40_2
+; NOSFB-NEXT: # %bb.1: # %entry
+; NOSFB-NEXT: slli a0, a0, 31
+; NOSFB-NEXT: srai a1, a0, 17
+; NOSFB-NEXT: .LBB40_2: # %entry
+; NOSFB-NEXT: mv a0, a1
+; NOSFB-NEXT: ret
+;
+; RV64SFBSIFIVEU74-LABEL: select_bfos:
+; RV64SFBSIFIVEU74: # %bb.0: # %entry
+; RV64SFBSIFIVEU74-NEXT: slli a0, a0, 31
+; RV64SFBSIFIVEU74-NEXT: bnez a2, .LBB40_2
+; RV64SFBSIFIVEU74-NEXT: # %bb.1: # %entry
+; RV64SFBSIFIVEU74-NEXT: srai a1, a0, 17
+; RV64SFBSIFIVEU74-NEXT: .LBB40_2: # %entry
+; RV64SFBSIFIVEU74-NEXT: mv a0, a1
+; RV64SFBSIFIVEU74-NEXT: ret
+;
+; RV64SFBANDESAX45-LABEL: select_bfos:
+; RV64SFBANDESAX45: # %bb.0: # %entry
+; RV64SFBANDESAX45-NEXT: nds.bfos a0, a0, 14, 46
+; RV64SFBANDESAX45-NEXT: beqz a2, .LBB40_2
+; RV64SFBANDESAX45-NEXT: # %bb.1: # %entry
+; RV64SFBANDESAX45-NEXT: mv a0, a1
+; RV64SFBANDESAX45-NEXT: .LBB40_2: # %entry
+; RV64SFBANDESAX45-NEXT: ret
+;
+; ZICOND-LABEL: select_bfos:
+; ZICOND: # %bb.0: # %entry
+; ZICOND-NEXT: slli a0, a0, 31
+; ZICOND-NEXT: bnez a2, .LBB40_2
+; ZICOND-NEXT: # %bb.1: # %entry
+; ZICOND-NEXT: srai a1, a0, 17
+; ZICOND-NEXT: .LBB40_2: # %entry
+; ZICOND-NEXT: mv a0, a1
+; ZICOND-NEXT: ret
+;
+; RV32SFB-LABEL: select_bfos:
+; RV32SFB: # %bb.0: # %entry
+; RV32SFB-NEXT: srli a5, a0, 1
+; RV32SFB-NEXT: slli a6, a1, 31
+; RV32SFB-NEXT: slli a0, a0, 31
+; RV32SFB-NEXT: slli a1, a5, 15
+; RV32SFB-NEXT: srli a0, a0, 17
+; RV32SFB-NEXT: or a5, a6, a5
+; RV32SFB-NEXT: bnez a4, .LBB40_2
+; RV32SFB-NEXT: # %bb.1: # %entry
+; RV32SFB-NEXT: or a2, a0, a1
+; RV32SFB-NEXT: .LBB40_2: # %entry
+; RV32SFB-NEXT: bnez a4, .LBB40_4
+; RV32SFB-NEXT: # %bb.3: # %entry
+; RV32SFB-NEXT: srai a3, a5, 17
+; RV32SFB-NEXT: .LBB40_4: # %entry
+; RV32SFB-NEXT: mv a0, a2
+; RV32SFB-NEXT: mv a1, a3
+; RV32SFB-NEXT: ret
+entry:
+ %0 = shl i64 %A, 31
+ %1 = ashr i64 %0, 17
+ %2 = select i1 %cond, i64 %B, i64 %1
+ ret i64 %2
+}
>From 0ac294d6f0a23bf55d5bccb72440941588c8784b Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Thu, 26 Jun 2025 10:02:40 +0800
Subject: [PATCH 2/2] [RISCV] Add nds.bfos and nds.bfoz for the short forward
branch optimization.
This adds nds.bfos and nds.bfoz, which are also supported by Andes
45-series CPUs for short forward branch optimization.
---
.../Target/RISCV/RISCVExpandPseudoInsts.cpp | 18 +++++++++++++++---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 3 +++
llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td | 18 ++++++++++++++++++
.../CodeGen/RISCV/short-forward-branch-opt.ll | 12 ++++++------
4 files changed, 42 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
index d3dce4edb1e75..bd2f0e6b794f5 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
@@ -147,6 +147,8 @@ bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
case RISCV::PseudoCCANDN:
case RISCV::PseudoCCORN:
case RISCV::PseudoCCXNOR:
+ case RISCV::PseudoCCNDS_BFOS:
+ case RISCV::PseudoCCNDS_BFOZ:
return expandCCOp(MBB, MBBI, NextMBBI);
case RISCV::PseudoVMCLR_M_B1:
case RISCV::PseudoVMCLR_M_B2:
@@ -240,10 +242,20 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
case RISCV::PseudoCCANDN: NewOpc = RISCV::ANDN; break;
case RISCV::PseudoCCORN: NewOpc = RISCV::ORN; break;
case RISCV::PseudoCCXNOR: NewOpc = RISCV::XNOR; break;
+ case RISCV::PseudoCCNDS_BFOS: NewOpc = RISCV::NDS_BFOS; break;
+ case RISCV::PseudoCCNDS_BFOZ: NewOpc = RISCV::NDS_BFOZ; break;
+ }
+
+ if (NewOpc == RISCV::NDS_BFOZ || NewOpc == RISCV::NDS_BFOS) {
+ BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg)
+ .add(MI.getOperand(5))
+ .add(MI.getOperand(6))
+ .add(MI.getOperand(7));
+ } else {
+ BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg)
+ .add(MI.getOperand(5))
+ .add(MI.getOperand(6));
}
- BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg)
- .add(MI.getOperand(5))
- .add(MI.getOperand(6));
}
TrueBB->addSuccessor(MergeBB);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 5711f0077b12d..f703a69cc9a2e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -1575,6 +1575,9 @@ unsigned getPredicatedOpcode(unsigned Opcode) {
case RISCV::ANDN: return RISCV::PseudoCCANDN; break;
case RISCV::ORN: return RISCV::PseudoCCORN; break;
case RISCV::XNOR: return RISCV::PseudoCCXNOR; break;
+
+ case RISCV::NDS_BFOS: return RISCV::PseudoCCNDS_BFOS; break;
+ case RISCV::NDS_BFOZ: return RISCV::PseudoCCNDS_BFOZ; break;
}
return RISCV::INSTRUCTION_LIST_END;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
index 0e2fcd2336151..3d2b9c209dc59 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
@@ -625,3 +625,21 @@ defset list<VTypeInfoToWide> AllQuadWidenableVD4DOTVectors = {
defm : VPatTernaryVD4DOT_VV<"int_riscv_nds_vd4dots", "PseudoNDS_VD4DOTS", AllQuadWidenableVD4DOTVectors>;
defm : VPatTernaryVD4DOT_VV<"int_riscv_nds_vd4dotu", "PseudoNDS_VD4DOTU", AllQuadWidenableVD4DOTVectors>;
defm : VPatTernaryVD4DOT_VV<"int_riscv_nds_vd4dotsu", "PseudoNDS_VD4DOTSU", AllQuadWidenableVD4DOTVectors>;
+
+//===----------------------------------------------------------------------===//
+// Pseudo-instructions for SFB (Short Forward Branch)
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasShortForwardBranchOpt], hasSideEffects = 0,
+ mayLoad = 0, mayStore = 0, Size = 8, Constraints = "$dst = $falsev" in {
+def PseudoCCNDS_BFOS : Pseudo<(outs GPR:$dst),
+ (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
+ GPR:$falsev, GPR:$rs1, uimmlog2xlen:$msb, uimmlog2xlen:$lsb), []>,
+ Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
+ ReadSFBALU]>;
+def PseudoCCNDS_BFOZ : Pseudo<(outs GPR:$dst),
+ (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
+ GPR:$falsev, GPR:$rs1, uimmlog2xlen:$msb, uimmlog2xlen:$lsb), []>,
+ Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
+ ReadSFBALU]>;
+}
diff --git a/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll b/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll
index 0b32f19147796..990039d765df8 100644
--- a/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll
+++ b/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll
@@ -1731,11 +1731,11 @@ define i64 @select_bfoz(i64 %A, i64 %B, i1 zeroext %cond) {
;
; RV64SFBANDESAX45-LABEL: select_bfoz:
; RV64SFBANDESAX45: # %bb.0: # %entry
-; RV64SFBANDESAX45-NEXT: nds.bfoz a0, a0, 25, 23
-; RV64SFBANDESAX45-NEXT: beqz a2, .LBB39_2
+; RV64SFBANDESAX45-NEXT: bnez a2, .LBB39_2
; RV64SFBANDESAX45-NEXT: # %bb.1: # %entry
-; RV64SFBANDESAX45-NEXT: mv a0, a1
+; RV64SFBANDESAX45-NEXT: nds.bfoz a1, a0, 25, 23
; RV64SFBANDESAX45-NEXT: .LBB39_2: # %entry
+; RV64SFBANDESAX45-NEXT: mv a0, a1
; RV64SFBANDESAX45-NEXT: ret
;
; ZICOND-LABEL: select_bfoz:
@@ -1792,11 +1792,11 @@ define i64 @select_bfos(i64 %A, i64 %B, i1 zeroext %cond) {
;
; RV64SFBANDESAX45-LABEL: select_bfos:
; RV64SFBANDESAX45: # %bb.0: # %entry
-; RV64SFBANDESAX45-NEXT: nds.bfos a0, a0, 14, 46
-; RV64SFBANDESAX45-NEXT: beqz a2, .LBB40_2
+; RV64SFBANDESAX45-NEXT: bnez a2, .LBB40_2
; RV64SFBANDESAX45-NEXT: # %bb.1: # %entry
-; RV64SFBANDESAX45-NEXT: mv a0, a1
+; RV64SFBANDESAX45-NEXT: nds.bfos a1, a0, 14, 46
; RV64SFBANDESAX45-NEXT: .LBB40_2: # %entry
+; RV64SFBANDESAX45-NEXT: mv a0, a1
; RV64SFBANDESAX45-NEXT: ret
;
; ZICOND-LABEL: select_bfos:
More information about the llvm-commits
mailing list