Skip to content

Commit 93395da

Browse files
tclin914svkeerthy
authored andcommitted
[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`
1 parent ee07a46 commit 93395da

File tree

4 files changed

+140
-13
lines changed

4 files changed

+140
-13
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: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,74 @@
22
; RUN: llc -O0 -mtriple=riscv32 -mattr=+xandesperf -verify-machineinstrs < %s \
33
; RUN: | FileCheck %s
44

5+
define i32 @bfoz_from_and_i32(i32 %x) {
6+
; CHECK-LABEL: bfoz_from_and_i32:
7+
; CHECK: # %bb.0:
8+
; CHECK-NEXT: nds.bfoz a0, a0, 11, 0
9+
; CHECK-NEXT: ret
10+
%a = and i32 %x, 4095
11+
ret i32 %a
12+
}
13+
14+
define i64 @bfoz_from_and_i64(i64 %x) {
15+
; CHECK-LABEL: bfoz_from_and_i64:
16+
; CHECK: # %bb.0:
17+
; CHECK-NEXT: # kill: def $x11 killed $x10
18+
; CHECK-NEXT: nds.bfoz a0, a0, 11, 0
19+
; CHECK-NEXT: li a1, 0
20+
; CHECK-NEXT: ret
21+
%a = and i64 %x, 4095
22+
ret i64 %a
23+
}
24+
25+
define i32 @bfoz_from_and_lshr_i32(i32 %x) {
26+
; CHECK-LABEL: bfoz_from_and_lshr_i32:
27+
; CHECK: # %bb.0:
28+
; CHECK-NEXT: nds.bfoz a0, a0, 25, 23
29+
; CHECK-NEXT: ret
30+
%shifted = lshr i32 %x, 23
31+
%masked = and i32 %shifted, 7
32+
ret i32 %masked
33+
}
34+
35+
define i64 @bfoz_from_and_lshr_i64(i64 %x) {
36+
; CHECK-LABEL: bfoz_from_and_lshr_i64:
37+
; CHECK: # %bb.0:
38+
; CHECK-NEXT: # kill: def $x12 killed $x11
39+
; CHECK-NEXT: nds.bfoz a0, a1, 25, 14
40+
; CHECK-NEXT: li a1, 0
41+
; CHECK-NEXT: ret
42+
%shifted = lshr i64 %x, 46
43+
%masked = and i64 %shifted, 4095
44+
ret i64 %masked
45+
}
46+
47+
define i32 @bfoz_from_lshr_and_i32(i32 %x) {
48+
; CHECK-LABEL: bfoz_from_lshr_and_i32:
49+
; CHECK: # %bb.0:
50+
; CHECK-NEXT: nds.bfoz a0, a0, 23, 12
51+
; CHECK-NEXT: ret
52+
%masked = and i32 %x, 16773120
53+
%shifted = lshr i32 %masked, 12
54+
ret i32 %shifted
55+
}
56+
57+
define i64 @bfoz_from_lshr_and_i64(i64 %x) {
58+
; CHECK-LABEL: bfoz_from_lshr_and_i64:
59+
; CHECK: # %bb.0:
60+
; CHECK-NEXT: # kill: def $x12 killed $x11
61+
; CHECK-NEXT: # kill: def $x12 killed $x10
62+
; CHECK-NEXT: andi a1, a1, 15
63+
; CHECK-NEXT: srli a0, a0, 24
64+
; CHECK-NEXT: slli a1, a1, 8
65+
; CHECK-NEXT: or a0, a0, a1
66+
; CHECK-NEXT: li a1, 0
67+
; CHECK-NEXT: ret
68+
%masked = and i64 %x, 68702699520
69+
%shifted = lshr i64 %masked, 24
70+
ret i64 %shifted
71+
}
72+
573
define i32 @sexti1_i32(i32 %a) {
674
; CHECK-LABEL: sexti1_i32:
775
; CHECK: # %bb.0:

llvm/test/CodeGen/RISCV/rv64xandesperf.ll

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,64 @@
22
; RUN: llc -mtriple=riscv64 -mattr=+xandesperf -verify-machineinstrs < %s \
33
; RUN: | FileCheck %s
44

5+
define i32 @bfoz_from_and_i32(i32 %x) {
6+
; CHECK-LABEL: bfoz_from_and_i32:
7+
; CHECK: # %bb.0:
8+
; CHECK-NEXT: nds.bfoz a0, a0, 11, 0
9+
; CHECK-NEXT: ret
10+
%a = and i32 %x, 4095
11+
ret i32 %a
12+
}
13+
14+
define i64 @bfoz_from_and_i64(i64 %x) {
15+
; CHECK-LABEL: bfoz_from_and_i64:
16+
; CHECK: # %bb.0:
17+
; CHECK-NEXT: nds.bfoz a0, a0, 11, 0
18+
; CHECK-NEXT: ret
19+
%a = and i64 %x, 4095
20+
ret i64 %a
21+
}
22+
23+
define i32 @bfoz_from_and_lshr_i32(i32 %x) {
24+
; CHECK-LABEL: bfoz_from_and_lshr_i32:
25+
; CHECK: # %bb.0:
26+
; CHECK-NEXT: nds.bfoz a0, a0, 25, 23
27+
; CHECK-NEXT: ret
28+
%shifted = lshr i32 %x, 23
29+
%masked = and i32 %shifted, 7
30+
ret i32 %masked
31+
}
32+
33+
define i64 @bfoz_from_and_lshr_i64(i64 %x) {
34+
; CHECK-LABEL: bfoz_from_and_lshr_i64:
35+
; CHECK: # %bb.0:
36+
; CHECK-NEXT: nds.bfoz a0, a0, 57, 46
37+
; CHECK-NEXT: ret
38+
%shifted = lshr i64 %x, 46
39+
%masked = and i64 %shifted, 4095
40+
ret i64 %masked
41+
}
42+
43+
define i32 @bfoz_from_lshr_and_i32(i32 %x) {
44+
; CHECK-LABEL: bfoz_from_lshr_and_i32:
45+
; CHECK: # %bb.0:
46+
; CHECK-NEXT: nds.bfoz a0, a0, 23, 12
47+
; CHECK-NEXT: ret
48+
%masked = and i32 %x, 16773120
49+
%shifted = lshr i32 %masked, 12
50+
ret i32 %shifted
51+
}
52+
53+
define i64 @bfoz_from_lshr_and_i64(i64 %x) {
54+
; CHECK-LABEL: bfoz_from_lshr_and_i64:
55+
; CHECK: # %bb.0:
56+
; CHECK-NEXT: nds.bfoz a0, a0, 35, 24
57+
; CHECK-NEXT: ret
58+
%masked = and i64 %x, 68702699520
59+
%shifted = lshr i64 %masked, 24
60+
ret i64 %shifted
61+
}
62+
563
define signext i32 @sexti1_i32(i32 signext %a) {
664
; CHECK-LABEL: sexti1_i32:
765
; CHECK: # %bb.0:

llvm/test/CodeGen/RISCV/rv64zba.ll

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ define i64 @zextw_i64(i64 %a) nounwind {
126126
;
127127
; RV64XANDESPERF-LABEL: zextw_i64:
128128
; RV64XANDESPERF: # %bb.0:
129-
; RV64XANDESPERF-NEXT: nds.lea.b.ze a0, zero, a0
129+
; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 31, 0
130130
; RV64XANDESPERF-NEXT: ret
131131
%and = and i64 %a, 4294967295
132132
ret i64 %and
@@ -151,7 +151,7 @@ define i64 @zextw_demandedbits_i64(i64 %0) {
151151
; RV64XANDESPERF-LABEL: zextw_demandedbits_i64:
152152
; RV64XANDESPERF: # %bb.0:
153153
; RV64XANDESPERF-NEXT: ori a0, a0, 1
154-
; RV64XANDESPERF-NEXT: nds.lea.b.ze a0, zero, a0
154+
; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 31, 0
155155
; RV64XANDESPERF-NEXT: ret
156156
%2 = and i64 %0, 4294967294
157157
%3 = or i64 %2, 1
@@ -1577,7 +1577,7 @@ define i64 @adduw_imm(i32 signext %0) nounwind {
15771577
;
15781578
; RV64XANDESPERF-LABEL: adduw_imm:
15791579
; RV64XANDESPERF: # %bb.0:
1580-
; RV64XANDESPERF-NEXT: nds.lea.b.ze a0, zero, a0
1580+
; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 31, 0
15811581
; RV64XANDESPERF-NEXT: addi a0, a0, 5
15821582
; RV64XANDESPERF-NEXT: ret
15831583
%a = zext i32 %0 to i64
@@ -2324,8 +2324,7 @@ define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
23242324
; RV64XANDESPERF-LABEL: sext_ashr_zext_i8:
23252325
; RV64XANDESPERF: # %bb.0:
23262326
; RV64XANDESPERF-NEXT: nds.bfos a0, a0, 7, 0
2327-
; RV64XANDESPERF-NEXT: slli a0, a0, 23
2328-
; RV64XANDESPERF-NEXT: srli a0, a0, 32
2327+
; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 40, 9
23292328
; RV64XANDESPERF-NEXT: ret
23302329
%ext = sext i8 %a to i32
23312330
%1 = ashr i32 %ext, 9
@@ -2473,8 +2472,7 @@ define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
24732472
; RV64XANDESPERF-LABEL: sext_ashr_zext_i16:
24742473
; RV64XANDESPERF: # %bb.0:
24752474
; RV64XANDESPERF-NEXT: nds.bfos a0, a0, 15, 0
2476-
; RV64XANDESPERF-NEXT: slli a0, a0, 23
2477-
; RV64XANDESPERF-NEXT: srli a0, a0, 32
2475+
; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 40, 9
24782476
; RV64XANDESPERF-NEXT: ret
24792477
%ext = sext i16 %a to i32
24802478
%1 = ashr i32 %ext, 9

0 commit comments

Comments
 (0)