[llvm] dd885f1 - [RISCV] Select unsigned bitfield extracts for XAndesPerf (#141398)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 28 19:52:36 PDT 2025
Author: Jim Lin
Date: 2025-05-29T10:52:33+08:00
New Revision: dd885f1f68a2667d285113d758d3e6d868858e09
URL: https://github.com/llvm/llvm-project/commit/dd885f1f68a2667d285113d758d3e6d868858e09
DIFF: https://github.com/llvm/llvm-project/commit/dd885f1f68a2667d285113d758d3e6d868858e09.diff
LOG: [RISCV] Select unsigned bitfield extracts for XAndesPerf (#141398)
The XAndesPerf extension includes unsigned bitfield extraction
instruction `NDS.BFOZ`, which can extract the bits from LSB to MSB,
places them starting at bit 0, and zero-extends the result.
The testcase includes the three patterns that can be selected as
unsigned bitfield extracts: `and`, `and+lshr` and `lshr+and`
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
llvm/test/CodeGen/RISCV/rv32xandesperf.ll
llvm/test/CodeGen/RISCV/rv64xandesperf.ll
llvm/test/CodeGen/RISCV/rv64zba.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index ccb798268fb60..2de22ee165aea 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -672,14 +672,17 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
bool RISCVDAGToDAGISel::tryUnsignedBitfieldExtract(SDNode *Node, SDLoc DL,
MVT VT, SDValue X,
unsigned Msb, unsigned Lsb) {
- // 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;
- SDNode *TH_EXTU = CurDAG->getMachineNode(
- RISCV::TH_EXTU, DL, VT, X, CurDAG->getTargetConstant(Msb, DL, VT),
- CurDAG->getTargetConstant(Lsb, DL, VT));
- ReplaceNode(Node, TH_EXTU);
+ unsigned Opc =
+ Subtarget->hasVendorXTHeadBb() ? RISCV::TH_EXTU : RISCV::NDS_BFOZ;
+
+ SDNode *Ube = CurDAG->getMachineNode(Opc, DL, VT, X,
+ CurDAG->getTargetConstant(Msb, DL, VT),
+ CurDAG->getTargetConstant(Lsb, DL, VT));
+ ReplaceNode(Node, Ube);
return true;
}
diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
index efe5b4a306fee..72dddddf9f382 100644
--- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
@@ -2,6 +2,74 @@
; RUN: llc -O0 -mtriple=riscv32 -mattr=+xandesperf -verify-machineinstrs < %s \
; RUN: | FileCheck %s
+define i32 @bfoz_from_and_i32(i32 %x) {
+; CHECK-LABEL: bfoz_from_and_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfoz a0, a0, 11, 0
+; CHECK-NEXT: ret
+ %a = and i32 %x, 4095
+ ret i32 %a
+}
+
+define i64 @bfoz_from_and_i64(i64 %x) {
+; CHECK-LABEL: bfoz_from_and_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfoz a0, a0, 11, 0
+; CHECK-NEXT: li a1, 0
+; CHECK-NEXT: ret
+ %a = and i64 %x, 4095
+ ret i64 %a
+}
+
+define i32 @bfoz_from_and_lshr_i32(i32 %x) {
+; CHECK-LABEL: bfoz_from_and_lshr_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfoz a0, a0, 25, 23
+; CHECK-NEXT: ret
+ %shifted = lshr i32 %x, 23
+ %masked = and i32 %shifted, 7
+ ret i32 %masked
+}
+
+define i64 @bfoz_from_and_lshr_i64(i64 %x) {
+; CHECK-LABEL: bfoz_from_and_lshr_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x12 killed $x11
+; CHECK-NEXT: nds.bfoz a0, a1, 25, 14
+; CHECK-NEXT: li a1, 0
+; CHECK-NEXT: ret
+ %shifted = lshr i64 %x, 46
+ %masked = and i64 %shifted, 4095
+ ret i64 %masked
+}
+
+define i32 @bfoz_from_lshr_and_i32(i32 %x) {
+; CHECK-LABEL: bfoz_from_lshr_and_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfoz a0, a0, 23, 12
+; CHECK-NEXT: ret
+ %masked = and i32 %x, 16773120
+ %shifted = lshr i32 %masked, 12
+ ret i32 %shifted
+}
+
+define i64 @bfoz_from_lshr_and_i64(i64 %x) {
+; CHECK-LABEL: bfoz_from_lshr_and_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x12 killed $x11
+; CHECK-NEXT: # kill: def $x12 killed $x10
+; CHECK-NEXT: andi a1, a1, 15
+; CHECK-NEXT: srli a0, a0, 24
+; CHECK-NEXT: slli a1, a1, 8
+; CHECK-NEXT: or a0, a0, a1
+; CHECK-NEXT: li a1, 0
+; CHECK-NEXT: ret
+ %masked = and i64 %x, 68702699520
+ %shifted = lshr i64 %masked, 24
+ ret i64 %shifted
+}
+
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 9cc95ce886133..13c2234071eb1 100644
--- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
@@ -2,6 +2,64 @@
; RUN: llc -mtriple=riscv64 -mattr=+xandesperf -verify-machineinstrs < %s \
; RUN: | FileCheck %s
+define i32 @bfoz_from_and_i32(i32 %x) {
+; CHECK-LABEL: bfoz_from_and_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfoz a0, a0, 11, 0
+; CHECK-NEXT: ret
+ %a = and i32 %x, 4095
+ ret i32 %a
+}
+
+define i64 @bfoz_from_and_i64(i64 %x) {
+; CHECK-LABEL: bfoz_from_and_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfoz a0, a0, 11, 0
+; CHECK-NEXT: ret
+ %a = and i64 %x, 4095
+ ret i64 %a
+}
+
+define i32 @bfoz_from_and_lshr_i32(i32 %x) {
+; CHECK-LABEL: bfoz_from_and_lshr_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfoz a0, a0, 25, 23
+; CHECK-NEXT: ret
+ %shifted = lshr i32 %x, 23
+ %masked = and i32 %shifted, 7
+ ret i32 %masked
+}
+
+define i64 @bfoz_from_and_lshr_i64(i64 %x) {
+; CHECK-LABEL: bfoz_from_and_lshr_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfoz a0, a0, 57, 46
+; CHECK-NEXT: ret
+ %shifted = lshr i64 %x, 46
+ %masked = and i64 %shifted, 4095
+ ret i64 %masked
+}
+
+define i32 @bfoz_from_lshr_and_i32(i32 %x) {
+; CHECK-LABEL: bfoz_from_lshr_and_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfoz a0, a0, 23, 12
+; CHECK-NEXT: ret
+ %masked = and i32 %x, 16773120
+ %shifted = lshr i32 %masked, 12
+ ret i32 %shifted
+}
+
+define i64 @bfoz_from_lshr_and_i64(i64 %x) {
+; CHECK-LABEL: bfoz_from_lshr_and_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfoz a0, a0, 35, 24
+; CHECK-NEXT: ret
+ %masked = and i64 %x, 68702699520
+ %shifted = lshr i64 %masked, 24
+ ret i64 %shifted
+}
+
define signext i32 @sexti1_i32(i32 signext %a) {
; CHECK-LABEL: sexti1_i32:
; CHECK: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll
index 6bd808ca9e126..622b302da4c51 100644
--- a/llvm/test/CodeGen/RISCV/rv64zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zba.ll
@@ -126,7 +126,7 @@ define i64 @zextw_i64(i64 %a) nounwind {
;
; RV64XANDESPERF-LABEL: zextw_i64:
; RV64XANDESPERF: # %bb.0:
-; RV64XANDESPERF-NEXT: nds.lea.b.ze a0, zero, a0
+; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 31, 0
; RV64XANDESPERF-NEXT: ret
%and = and i64 %a, 4294967295
ret i64 %and
@@ -151,7 +151,7 @@ define i64 @zextw_demandedbits_i64(i64 %0) {
; RV64XANDESPERF-LABEL: zextw_demandedbits_i64:
; RV64XANDESPERF: # %bb.0:
; RV64XANDESPERF-NEXT: ori a0, a0, 1
-; RV64XANDESPERF-NEXT: nds.lea.b.ze a0, zero, a0
+; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 31, 0
; RV64XANDESPERF-NEXT: ret
%2 = and i64 %0, 4294967294
%3 = or i64 %2, 1
@@ -1577,7 +1577,7 @@ define i64 @adduw_imm(i32 signext %0) nounwind {
;
; RV64XANDESPERF-LABEL: adduw_imm:
; RV64XANDESPERF: # %bb.0:
-; RV64XANDESPERF-NEXT: nds.lea.b.ze a0, zero, a0
+; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 31, 0
; RV64XANDESPERF-NEXT: addi a0, a0, 5
; RV64XANDESPERF-NEXT: ret
%a = zext i32 %0 to i64
@@ -2324,8 +2324,7 @@ define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
; RV64XANDESPERF-LABEL: sext_ashr_zext_i8:
; RV64XANDESPERF: # %bb.0:
; RV64XANDESPERF-NEXT: nds.bfos a0, a0, 7, 0
-; RV64XANDESPERF-NEXT: slli a0, a0, 23
-; RV64XANDESPERF-NEXT: srli a0, a0, 32
+; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 40, 9
; RV64XANDESPERF-NEXT: ret
%ext = sext i8 %a to i32
%1 = ashr i32 %ext, 9
@@ -2473,8 +2472,7 @@ define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
; RV64XANDESPERF-LABEL: sext_ashr_zext_i16:
; RV64XANDESPERF: # %bb.0:
; RV64XANDESPERF-NEXT: nds.bfos a0, a0, 15, 0
-; RV64XANDESPERF-NEXT: slli a0, a0, 23
-; RV64XANDESPERF-NEXT: srli a0, a0, 32
+; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 40, 9
; RV64XANDESPERF-NEXT: ret
%ext = sext i16 %a to i32
%1 = ashr i32 %ext, 9
More information about the llvm-commits
mailing list