Skip to content

Commit 06cf15d

Browse files
committed
[RISCV] Select unsigned bitfiled extracts for XAndesPerf
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.
1 parent d1d3a32 commit 06cf15d

File tree

3 files changed

+20
-28
lines changed

3 files changed

+20
-28
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -672,14 +672,17 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
672672
bool RISCVDAGToDAGISel::tryUnsignedBitfieldExtract(SDNode *Node, SDLoc DL,
673673
MVT VT, SDValue X,
674674
unsigned Msb, unsigned Lsb) {
675-
// Only supported with XTHeadBb at the moment.
676-
if (!Subtarget->hasVendorXTHeadBb())
675+
// Only supported with XTHeadBb/XAndesPerf at the moment.
676+
if (!Subtarget->hasVendorXTHeadBb() && !Subtarget->hasVendorXAndesPerf())
677677
return false;
678678

679-
SDNode *TH_EXTU = CurDAG->getMachineNode(
680-
RISCV::TH_EXTU, DL, VT, X, CurDAG->getTargetConstant(Msb, DL, VT),
681-
CurDAG->getTargetConstant(Lsb, DL, VT));
682-
ReplaceNode(Node, TH_EXTU);
679+
unsigned Opc =
680+
Subtarget->hasVendorXTHeadBb() ? RISCV::TH_EXTU : RISCV::NDS_BFOZ;
681+
682+
SDNode *Ube = CurDAG->getMachineNode(Opc, DL, VT, X,
683+
CurDAG->getTargetConstant(Msb, DL, VT),
684+
CurDAG->getTargetConstant(Lsb, DL, VT));
685+
ReplaceNode(Node, Ube);
683686
return true;
684687
}
685688

llvm/test/CodeGen/RISCV/rv32xandesperf.ll

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
define i32 @bfoz_from_and_i32(i32 %x) {
66
; CHECK-LABEL: bfoz_from_and_i32:
77
; CHECK: # %bb.0:
8-
; CHECK-NEXT: slli a0, a0, 20
9-
; CHECK-NEXT: srli a0, a0, 20
8+
; CHECK-NEXT: nds.bfoz a0, a0, 11, 0
109
; CHECK-NEXT: ret
1110
%a = and i32 %x, 4095
1211
ret i32 %a
@@ -16,8 +15,7 @@ define i64 @bfoz_from_and_i64(i64 %x) {
1615
; CHECK-LABEL: bfoz_from_and_i64:
1716
; CHECK: # %bb.0:
1817
; CHECK-NEXT: # kill: def $x11 killed $x10
19-
; CHECK-NEXT: slli a0, a0, 20
20-
; CHECK-NEXT: srli a0, a0, 20
18+
; CHECK-NEXT: nds.bfoz a0, a0, 11, 0
2119
; CHECK-NEXT: li a1, 0
2220
; CHECK-NEXT: ret
2321
%a = and i64 %x, 4095
@@ -27,8 +25,7 @@ define i64 @bfoz_from_and_i64(i64 %x) {
2725
define i32 @bfoz_from_and_lshr_i32(i32 %x) {
2826
; CHECK-LABEL: bfoz_from_and_lshr_i32:
2927
; CHECK: # %bb.0:
30-
; CHECK-NEXT: slli a0, a0, 6
31-
; CHECK-NEXT: srli a0, a0, 29
28+
; CHECK-NEXT: nds.bfoz a0, a0, 25, 23
3229
; CHECK-NEXT: ret
3330
%shifted = lshr i32 %x, 23
3431
%masked = and i32 %shifted, 7
@@ -39,8 +36,7 @@ define i64 @bfoz_from_and_lshr_i64(i64 %x) {
3936
; CHECK-LABEL: bfoz_from_and_lshr_i64:
4037
; CHECK: # %bb.0:
4138
; CHECK-NEXT: # kill: def $x12 killed $x11
42-
; CHECK-NEXT: slli a0, a1, 6
43-
; CHECK-NEXT: srli a0, a0, 20
39+
; CHECK-NEXT: nds.bfoz a0, a1, 25, 14
4440
; CHECK-NEXT: li a1, 0
4541
; CHECK-NEXT: ret
4642
%shifted = lshr i64 %x, 46
@@ -51,8 +47,7 @@ define i64 @bfoz_from_and_lshr_i64(i64 %x) {
5147
define i32 @bfoz_from_lshr_and_i32(i32 %x) {
5248
; CHECK-LABEL: bfoz_from_lshr_and_i32:
5349
; CHECK: # %bb.0:
54-
; CHECK-NEXT: slli a0, a0, 8
55-
; CHECK-NEXT: srli a0, a0, 20
50+
; CHECK-NEXT: nds.bfoz a0, a0, 23, 12
5651
; CHECK-NEXT: ret
5752
%masked = and i32 %x, 16773120
5853
%shifted = lshr i32 %masked, 12

llvm/test/CodeGen/RISCV/rv64xandesperf.ll

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
define i32 @bfoz_from_and_i32(i32 %x) {
66
; CHECK-LABEL: bfoz_from_and_i32:
77
; CHECK: # %bb.0:
8-
; CHECK-NEXT: slli a0, a0, 52
9-
; CHECK-NEXT: srli a0, a0, 52
8+
; CHECK-NEXT: nds.bfoz a0, a0, 11, 0
109
; CHECK-NEXT: ret
1110
%a = and i32 %x, 4095
1211
ret i32 %a
@@ -15,8 +14,7 @@ define i32 @bfoz_from_and_i32(i32 %x) {
1514
define i64 @bfoz_from_and_i64(i64 %x) {
1615
; CHECK-LABEL: bfoz_from_and_i64:
1716
; CHECK: # %bb.0:
18-
; CHECK-NEXT: slli a0, a0, 52
19-
; CHECK-NEXT: srli a0, a0, 52
17+
; CHECK-NEXT: nds.bfoz a0, a0, 11, 0
2018
; CHECK-NEXT: ret
2119
%a = and i64 %x, 4095
2220
ret i64 %a
@@ -25,8 +23,7 @@ define i64 @bfoz_from_and_i64(i64 %x) {
2523
define i32 @bfoz_from_and_lshr_i32(i32 %x) {
2624
; CHECK-LABEL: bfoz_from_and_lshr_i32:
2725
; CHECK: # %bb.0:
28-
; CHECK-NEXT: slli a0, a0, 38
29-
; CHECK-NEXT: srli a0, a0, 61
26+
; CHECK-NEXT: nds.bfoz a0, a0, 25, 23
3027
; CHECK-NEXT: ret
3128
%shifted = lshr i32 %x, 23
3229
%masked = and i32 %shifted, 7
@@ -36,8 +33,7 @@ define i32 @bfoz_from_and_lshr_i32(i32 %x) {
3633
define i64 @bfoz_from_and_lshr_i64(i64 %x) {
3734
; CHECK-LABEL: bfoz_from_and_lshr_i64:
3835
; CHECK: # %bb.0:
39-
; CHECK-NEXT: slli a0, a0, 6
40-
; CHECK-NEXT: srli a0, a0, 52
36+
; CHECK-NEXT: nds.bfoz a0, a0, 57, 46
4137
; CHECK-NEXT: ret
4238
%shifted = lshr i64 %x, 46
4339
%masked = and i64 %shifted, 4095
@@ -47,8 +43,7 @@ define i64 @bfoz_from_and_lshr_i64(i64 %x) {
4743
define i32 @bfoz_from_lshr_and_i32(i32 %x) {
4844
; CHECK-LABEL: bfoz_from_lshr_and_i32:
4945
; CHECK: # %bb.0:
50-
; CHECK-NEXT: slli a0, a0, 40
51-
; CHECK-NEXT: srli a0, a0, 52
46+
; CHECK-NEXT: nds.bfoz a0, a0, 23, 12
5247
; CHECK-NEXT: ret
5348
%masked = and i32 %x, 16773120
5449
%shifted = lshr i32 %masked, 12
@@ -58,8 +53,7 @@ define i32 @bfoz_from_lshr_and_i32(i32 %x) {
5853
define i64 @bfoz_from_lshr_and_i64(i64 %x) {
5954
; CHECK-LABEL: bfoz_from_lshr_and_i64:
6055
; CHECK: # %bb.0:
61-
; CHECK-NEXT: slli a0, a0, 28
62-
; CHECK-NEXT: srli a0, a0, 52
56+
; CHECK-NEXT: nds.bfoz a0, a0, 35, 24
6357
; CHECK-NEXT: ret
6458
%masked = and i64 %x, 68702699520
6559
%shifted = lshr i64 %masked, 24

0 commit comments

Comments
 (0)