Skip to content

Commit d2e56f4

Browse files
committed
[RISCV] Select signed bitfield insert for XAndesPerf
1 parent 9795481 commit d2e56f4

File tree

4 files changed

+63
-12
lines changed

4 files changed

+63
-12
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,59 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
683683
return false;
684684
}
685685

686+
bool RISCVDAGToDAGISel::trySignedBitfieldInsertInSign(SDNode *Node) {
687+
// Only supported with XAndesPerf at the moment.
688+
if (!Subtarget->hasVendorXAndesPerf())
689+
return false;
690+
691+
auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
692+
if (!N1C)
693+
return false;
694+
695+
SDValue N0 = Node->getOperand(0);
696+
if (!N0.hasOneUse())
697+
return false;
698+
699+
auto BitfieldInsert = [&](SDValue N0, unsigned Msb, unsigned Lsb, SDLoc DL,
700+
MVT VT) {
701+
unsigned Opc = RISCV::NDS_BFOS;
702+
// If the Lsb is equal to the Msb, then the Lsb should be 0.
703+
if (Lsb == Msb)
704+
Lsb = 0;
705+
return CurDAG->getMachineNode(Opc, DL, VT, N0.getOperand(0),
706+
CurDAG->getTargetConstant(Lsb, DL, VT),
707+
CurDAG->getTargetConstant(Msb, DL, VT));
708+
};
709+
710+
SDLoc DL(Node);
711+
MVT VT = Node->getSimpleValueType(0);
712+
const unsigned RightShAmt = N1C->getZExtValue();
713+
714+
// Transform (sra (shl X, C1) C2) with C1 > C2
715+
// -> (NDS.BFOS X, lsb, msb)
716+
if (N0.getOpcode() == ISD::SHL) {
717+
auto *N01C = dyn_cast<ConstantSDNode>(N0->getOperand(1));
718+
if (!N01C)
719+
return false;
720+
721+
const unsigned LeftShAmt = N01C->getZExtValue();
722+
// Make sure that this is a bitfield insertion (i.e., the shift-right
723+
// amount should be less than the left-shift).
724+
if (LeftShAmt <= RightShAmt)
725+
return false;
726+
727+
const unsigned MsbPlusOne = VT.getSizeInBits() - RightShAmt;
728+
const unsigned Msb = MsbPlusOne - 1;
729+
const unsigned Lsb = LeftShAmt - RightShAmt;
730+
731+
SDNode *Sbi = BitfieldInsert(N0, Msb, Lsb, DL, VT);
732+
ReplaceNode(Node, Sbi);
733+
return true;
734+
}
735+
736+
return false;
737+
}
738+
686739
bool RISCVDAGToDAGISel::tryUnsignedBitfieldExtract(SDNode *Node,
687740
const SDLoc &DL, MVT VT,
688741
SDValue X, unsigned Msb,
@@ -1214,6 +1267,9 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
12141267
if (trySignedBitfieldExtract(Node))
12151268
return;
12161269

1270+
if (trySignedBitfieldInsertInSign(Node))
1271+
return;
1272+
12171273
// Optimize (sra (sext_inreg X, i16), C) ->
12181274
// (srai (slli X, (XLen-16), (XLen-16) + C)
12191275
// And (sra (sext_inreg X, i8), C) ->

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
7777

7878
bool tryShrinkShlLogicImm(SDNode *Node);
7979
bool trySignedBitfieldExtract(SDNode *Node);
80+
bool trySignedBitfieldInsertInSign(SDNode *Node);
8081
bool tryUnsignedBitfieldExtract(SDNode *Node, const SDLoc &DL, MVT VT,
8182
SDValue X, unsigned Msb, unsigned Lsb);
8283
bool tryUnsignedBitfieldInsertInZero(SDNode *Node, const SDLoc &DL, MVT VT,

llvm/test/CodeGen/RISCV/rv32xandesperf.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,7 @@ define i32 @bfos_from_ashr_sexti16_i32(i16 %x) {
159159
define i32 @bfos_from_ashr_shl_with_msb_zero_insert_i32(i32 %x) {
160160
; CHECK-LABEL: bfos_from_ashr_shl_with_msb_zero_insert_i32:
161161
; CHECK: # %bb.0:
162-
; CHECK-NEXT: slli a0, a0, 31
163-
; CHECK-NEXT: srai a0, a0, 17
162+
; CHECK-NEXT: nds.bfos a0, a0, 0, 14
164163
; CHECK-NEXT: ret
165164
%shl = shl i32 %x, 31
166165
%lshr = ashr i32 %shl, 17
@@ -172,8 +171,7 @@ define i32 @bfos_from_ashr_shl_with_msb_zero_insert_i32(i32 %x) {
172171
define i32 @bfos_from_ashr_shl_insert_i32(i32 %x) {
173172
; CHECK-LABEL: bfos_from_ashr_shl_insert_i32:
174173
; CHECK: # %bb.0:
175-
; CHECK-NEXT: slli a0, a0, 29
176-
; CHECK-NEXT: srai a0, a0, 11
174+
; CHECK-NEXT: nds.bfos a0, a0, 18, 20
177175
; CHECK-NEXT: ret
178176
%shl = shl i32 %x, 29
179177
%lshr = ashr i32 %shl, 11

llvm/test/CodeGen/RISCV/rv64xandesperf.ll

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,7 @@ define i64 @bfos_from_ashr_sexti16_i64(i16 %x) {
217217
define i32 @bfos_from_ashr_shl_with_msb_zero_insert_i32(i32 %x) {
218218
; CHECK-LABEL: bfos_from_ashr_shl_with_msb_zero_insert_i32:
219219
; CHECK: # %bb.0:
220-
; CHECK-NEXT: slli a0, a0, 63
221-
; CHECK-NEXT: srai a0, a0, 49
220+
; CHECK-NEXT: nds.bfos a0, a0, 0, 14
222221
; CHECK-NEXT: ret
223222
%shl = shl i32 %x, 31
224223
%lshr = ashr i32 %shl, 17
@@ -228,8 +227,7 @@ define i32 @bfos_from_ashr_shl_with_msb_zero_insert_i32(i32 %x) {
228227
define i64 @bfos_from_ashr_shl_with_msb_zero_insert_i64(i64 %x) {
229228
; CHECK-LABEL: bfos_from_ashr_shl_with_msb_zero_insert_i64:
230229
; CHECK: # %bb.0:
231-
; CHECK-NEXT: slli a0, a0, 63
232-
; CHECK-NEXT: srai a0, a0, 17
230+
; CHECK-NEXT: nds.bfos a0, a0, 0, 46
233231
; CHECK-NEXT: ret
234232
%shl = shl i64 %x, 63
235233
%lshr = ashr i64 %shl, 17
@@ -241,8 +239,7 @@ define i64 @bfos_from_ashr_shl_with_msb_zero_insert_i64(i64 %x) {
241239
define i32 @bfos_from_ashr_shl_insert_i32(i32 %x) {
242240
; CHECK-LABEL: bfos_from_ashr_shl_insert_i32:
243241
; CHECK: # %bb.0:
244-
; CHECK-NEXT: slli a0, a0, 61
245-
; CHECK-NEXT: srai a0, a0, 43
242+
; CHECK-NEXT: nds.bfos a0, a0, 18, 20
246243
; CHECK-NEXT: ret
247244
%shl = shl i32 %x, 29
248245
%lshr = ashr i32 %shl, 11
@@ -252,8 +249,7 @@ define i32 @bfos_from_ashr_shl_insert_i32(i32 %x) {
252249
define i64 @bfos_from_ashr_shl_insert_i64(i64 %x) {
253250
; CHECK-LABEL: bfos_from_ashr_shl_insert_i64:
254251
; CHECK: # %bb.0:
255-
; CHECK-NEXT: slli a0, a0, 29
256-
; CHECK-NEXT: srai a0, a0, 11
252+
; CHECK-NEXT: nds.bfos a0, a0, 18, 52
257253
; CHECK-NEXT: ret
258254
%shl = shl i64 %x, 29
259255
%lshr = ashr i64 %shl, 11

0 commit comments

Comments
 (0)