Skip to content

Commit f90cfb1

Browse files
authored
[RISCV] Select signed bitfield extracts for XAndesPerf (#142303)
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`
1 parent 8808a54 commit f90cfb1

File tree

3 files changed

+97
-3
lines changed

3 files changed

+97
-3
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -601,8 +601,8 @@ bool RISCVDAGToDAGISel::tryShrinkShlLogicImm(SDNode *Node) {
601601
}
602602

603603
bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
604-
// Only supported with XTHeadBb at the moment.
605-
if (!Subtarget->hasVendorXTHeadBb())
604+
// Only supported with XTHeadBb/XAndesPerf at the moment.
605+
if (!Subtarget->hasVendorXTHeadBb() && !Subtarget->hasVendorXAndesPerf())
606606
return false;
607607

608608
auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
@@ -615,7 +615,9 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
615615

616616
auto BitfieldExtract = [&](SDValue N0, unsigned Msb, unsigned Lsb, SDLoc DL,
617617
MVT VT) {
618-
return CurDAG->getMachineNode(RISCV::TH_EXT, DL, VT, N0.getOperand(0),
618+
unsigned Opc =
619+
Subtarget->hasVendorXTHeadBb() ? RISCV::TH_EXT : RISCV::NDS_BFOS;
620+
return CurDAG->getMachineNode(Opc, DL, VT, N0.getOperand(0),
619621
CurDAG->getTargetConstant(Msb, DL, VT),
620622
CurDAG->getTargetConstant(Lsb, DL, VT));
621623
};

llvm/test/CodeGen/RISCV/rv32xandesperf.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,38 @@ define i64 @bfoz_from_lshr_and_i64(i64 %x) {
7070
ret i64 %shifted
7171
}
7272

73+
define i32 @bfos_from_ashr_shl_i32(i32 %x) {
74+
; CHECK-LABEL: bfos_from_ashr_shl_i32:
75+
; CHECK: # %bb.0:
76+
; CHECK-NEXT: nds.bfos a0, a0, 23, 16
77+
; CHECK-NEXT: ret
78+
%shl = shl i32 %x, 8
79+
%ashr = ashr i32 %shl, 24
80+
ret i32 %ashr
81+
}
82+
83+
define i32 @bfos_from_ashr_sexti8_i32(i8 %x) {
84+
; CHECK-LABEL: bfos_from_ashr_sexti8_i32:
85+
; CHECK: # %bb.0:
86+
; CHECK-NEXT: # kill: def $x11 killed $x10
87+
; CHECK-NEXT: nds.bfos a0, a0, 7, 5
88+
; CHECK-NEXT: ret
89+
%sext = sext i8 %x to i32
90+
%ashr = ashr i32 %sext, 5
91+
ret i32 %ashr
92+
}
93+
94+
define i32 @bfos_from_ashr_sexti16_i32(i16 %x) {
95+
; CHECK-LABEL: bfos_from_ashr_sexti16_i32:
96+
; CHECK: # %bb.0:
97+
; CHECK-NEXT: # kill: def $x11 killed $x10
98+
; CHECK-NEXT: nds.bfos a0, a0, 15, 11
99+
; CHECK-NEXT: ret
100+
%sext = sext i16 %x to i32
101+
%ashr = ashr i32 %sext, 11
102+
ret i32 %ashr
103+
}
104+
73105
define i32 @sexti1_i32(i32 %a) {
74106
; CHECK-LABEL: sexti1_i32:
75107
; CHECK: # %bb.0:

llvm/test/CodeGen/RISCV/rv64xandesperf.ll

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,66 @@ define i64 @bfoz_from_lshr_and_i64(i64 %x) {
6060
ret i64 %shifted
6161
}
6262

63+
define i32 @bfos_from_ashr_shl_i32(i32 %x) {
64+
; CHECK-LABEL: bfos_from_ashr_shl_i32:
65+
; CHECK: # %bb.0:
66+
; CHECK-NEXT: nds.bfos a0, a0, 23, 16
67+
; CHECK-NEXT: ret
68+
%shl = shl i32 %x, 8
69+
%ashr = ashr i32 %shl, 24
70+
ret i32 %ashr
71+
}
72+
73+
define i64 @bfos_from_ashr_shl_i64(i64 %x) {
74+
; CHECK-LABEL: bfos_from_ashr_shl_i64:
75+
; CHECK: # %bb.0:
76+
; CHECK-NEXT: nds.bfos a0, a0, 55, 16
77+
; CHECK-NEXT: ret
78+
%shl = shl i64 %x, 8
79+
%ashr = ashr i64 %shl, 24
80+
ret i64 %ashr
81+
}
82+
83+
define i32 @bfos_from_ashr_sexti8_i32(i8 %x) {
84+
; CHECK-LABEL: bfos_from_ashr_sexti8_i32:
85+
; CHECK: # %bb.0:
86+
; CHECK-NEXT: nds.bfos a0, a0, 7, 5
87+
; CHECK-NEXT: ret
88+
%sext = sext i8 %x to i32
89+
%ashr = ashr i32 %sext, 5
90+
ret i32 %ashr
91+
}
92+
93+
define i64 @bfos_from_ashr_sexti8_i64(i8 %x) {
94+
; CHECK-LABEL: bfos_from_ashr_sexti8_i64:
95+
; CHECK: # %bb.0:
96+
; CHECK-NEXT: nds.bfos a0, a0, 7, 5
97+
; CHECK-NEXT: ret
98+
%sext = sext i8 %x to i64
99+
%ashr = ashr i64 %sext, 5
100+
ret i64 %ashr
101+
}
102+
103+
define i32 @bfos_from_ashr_sexti16_i32(i16 %x) {
104+
; CHECK-LABEL: bfos_from_ashr_sexti16_i32:
105+
; CHECK: # %bb.0:
106+
; CHECK-NEXT: nds.bfos a0, a0, 15, 11
107+
; CHECK-NEXT: ret
108+
%sext = sext i16 %x to i32
109+
%ashr = ashr i32 %sext, 11
110+
ret i32 %ashr
111+
}
112+
113+
define i64 @bfos_from_ashr_sexti16_i64(i16 %x) {
114+
; CHECK-LABEL: bfos_from_ashr_sexti16_i64:
115+
; CHECK: # %bb.0:
116+
; CHECK-NEXT: nds.bfos a0, a0, 15, 11
117+
; CHECK-NEXT: ret
118+
%sext = sext i16 %x to i64
119+
%ashr = ashr i64 %sext, 11
120+
ret i64 %ashr
121+
}
122+
63123
define signext i32 @sexti1_i32(i32 signext %a) {
64124
; CHECK-LABEL: sexti1_i32:
65125
; CHECK: # %bb.0:

0 commit comments

Comments
 (0)