[llvm] [RISCV] Select signed bitfield extracts for XAndesPerf (PR #142303)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 1 01:18:07 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Jim Lin (tclin914)
<details>
<summary>Changes</summary>
The XAndesPerf extension includes signed bitfield extraction
instruction `NDS.BFOS`, which can extract the bits from LSB to MSB,
places them starting at bit 0, and sign-extends the result.
The testcase includes the two patterns that can be selected as
signed bitfield extracts: `ashr+shl` and `ashr+sext_inreg`
---
Full diff: https://github.com/llvm/llvm-project/pull/142303.diff
3 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp (+5-3)
- (modified) llvm/test/CodeGen/RISCV/rv32xandesperf.ll (+80)
- (modified) llvm/test/CodeGen/RISCV/rv64xandesperf.ll (+60)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 2de22ee165aea..4f6aa41d1e03b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -601,8 +601,8 @@ bool RISCVDAGToDAGISel::tryShrinkShlLogicImm(SDNode *Node) {
}
bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
- // Only supported with XTHeadBb at the moment.
- if (!Subtarget->hasVendorXTHeadBb())
+ // Only supported with XTHeadBb/XAndesPerf at the moment.
+ if (!Subtarget->hasVendorXTHeadBb() && !Subtarget->hasVendorXAndesPerf())
return false;
auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
@@ -615,7 +615,9 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
auto BitfieldExtract = [&](SDValue N0, unsigned Msb, unsigned Lsb, SDLoc DL,
MVT VT) {
- return CurDAG->getMachineNode(RISCV::TH_EXT, DL, VT, N0.getOperand(0),
+ unsigned Opc =
+ Subtarget->hasVendorXTHeadBb() ? RISCV::TH_EXT : RISCV::NDS_BFOS;
+ return CurDAG->getMachineNode(Opc, DL, VT, N0.getOperand(0),
CurDAG->getTargetConstant(Msb, DL, VT),
CurDAG->getTargetConstant(Lsb, DL, VT));
};
diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
index 72dddddf9f382..af353a1e541fe 100644
--- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
@@ -70,6 +70,86 @@ define i64 @bfoz_from_lshr_and_i64(i64 %x) {
ret i64 %shifted
}
+define i32 @bfos_from_ashr_shl_i32(i32 %x) {
+; CHECK-LABEL: bfos_from_ashr_shl_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 23, 16
+; CHECK-NEXT: ret
+ %shl = shl i32 %x, 8
+ %ashr = ashr i32 %shl, 24
+ ret i32 %ashr
+}
+
+define i64 @bfos_from_ashr_shl_i64(i64 %x) {
+; CHECK-LABEL: bfos_from_ashr_shl_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x12 killed $x11
+; CHECK-NEXT: # kill: def $x12 killed $x10
+; CHECK-NEXT: srli a2, a0, 24
+; CHECK-NEXT: slli a1, a1, 8
+; CHECK-NEXT: or a2, a1, a2
+; CHECK-NEXT: slli a2, a2, 8
+; CHECK-NEXT: nds.bfoz a0, a0, 23, 16
+; CHECK-NEXT: or a0, a0, a2
+; CHECK-NEXT: srai a1, a1, 24
+; CHECK-NEXT: ret
+ %shl = shl i64 %x, 8
+ %ashr = ashr i64 %shl, 24
+ ret i64 %ashr
+}
+
+define i32 @bfos_from_ashr_sexti8_i32(i8 %x) {
+; CHECK-LABEL: bfos_from_ashr_sexti8_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a0, a0, 7, 5
+; CHECK-NEXT: ret
+ %sext = sext i8 %x to i32
+ %ashr = ashr i32 %sext, 5
+ ret i32 %ashr
+}
+
+define i64 @bfos_from_ashr_sexti8_i64(i8 %x) {
+; CHECK-LABEL: bfos_from_ashr_sexti8_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a0, a0, 7, 0
+; CHECK-NEXT: srai a1, a0, 31
+; CHECK-NEXT: srli a0, a0, 5
+; CHECK-NEXT: slli a2, a1, 27
+; CHECK-NEXT: or a0, a0, a2
+; CHECK-NEXT: ret
+ %sext = sext i8 %x to i64
+ %ashr = ashr i64 %sext, 5
+ ret i64 %ashr
+}
+
+define i32 @bfos_from_ashr_sexti16_i32(i16 %x) {
+; CHECK-LABEL: bfos_from_ashr_sexti16_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a0, a0, 15, 11
+; CHECK-NEXT: ret
+ %sext = sext i16 %x to i32
+ %ashr = ashr i32 %sext, 11
+ ret i32 %ashr
+}
+
+define i64 @bfos_from_ashr_sexti16_i64(i16 %x) {
+; CHECK-LABEL: bfos_from_ashr_sexti16_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a0, a0, 15, 0
+; CHECK-NEXT: srai a1, a0, 31
+; CHECK-NEXT: srli a0, a0, 11
+; CHECK-NEXT: slli a2, a1, 21
+; CHECK-NEXT: or a0, a0, a2
+; CHECK-NEXT: ret
+ %sext = sext i16 %x to i64
+ %ashr = ashr i64 %sext, 11
+ ret i64 %ashr
+}
+
define i32 @sexti1_i32(i32 %a) {
; CHECK-LABEL: sexti1_i32:
; CHECK: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
index 13c2234071eb1..260d30be686dc 100644
--- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
@@ -60,6 +60,66 @@ define i64 @bfoz_from_lshr_and_i64(i64 %x) {
ret i64 %shifted
}
+define i32 @bfos_from_ashr_shl_i32(i32 %x) {
+; CHECK-LABEL: bfos_from_ashr_shl_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 23, 16
+; CHECK-NEXT: ret
+ %shl = shl i32 %x, 8
+ %ashr = ashr i32 %shl, 24
+ ret i32 %ashr
+}
+
+define i64 @bfos_from_ashr_shl_i64(i64 %x) {
+; CHECK-LABEL: bfos_from_ashr_shl_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 55, 16
+; CHECK-NEXT: ret
+ %shl = shl i64 %x, 8
+ %ashr = ashr i64 %shl, 24
+ ret i64 %ashr
+}
+
+define i32 @bfos_from_ashr_sexti8_i32(i8 %x) {
+; CHECK-LABEL: bfos_from_ashr_sexti8_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 7, 5
+; CHECK-NEXT: ret
+ %sext = sext i8 %x to i32
+ %ashr = ashr i32 %sext, 5
+ ret i32 %ashr
+}
+
+define i64 @bfos_from_ashr_sexti8_i64(i8 %x) {
+; CHECK-LABEL: bfos_from_ashr_sexti8_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 7, 5
+; CHECK-NEXT: ret
+ %sext = sext i8 %x to i64
+ %ashr = ashr i64 %sext, 5
+ ret i64 %ashr
+}
+
+define i32 @bfos_from_ashr_sexti16_i32(i16 %x) {
+; CHECK-LABEL: bfos_from_ashr_sexti16_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 15, 11
+; CHECK-NEXT: ret
+ %sext = sext i16 %x to i32
+ %ashr = ashr i32 %sext, 11
+ ret i32 %ashr
+}
+
+define i64 @bfos_from_ashr_sexti16_i64(i16 %x) {
+; CHECK-LABEL: bfos_from_ashr_sexti16_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 15, 11
+; CHECK-NEXT: ret
+ %sext = sext i16 %x to i64
+ %ashr = ashr i64 %sext, 11
+ ret i64 %ashr
+}
+
define signext i32 @sexti1_i32(i32 signext %a) {
; CHECK-LABEL: sexti1_i32:
; CHECK: # %bb.0:
``````````
</details>
https://github.com/llvm/llvm-project/pull/142303
More information about the llvm-commits
mailing list