Skip to content

Commit 17abc16

Browse files
authored
[RISCV] Support codegen for some scalar P extension instructions. (#164359)
This includes sext.b, sext.h, min/max, rev8, clz(w), and abs. Test cases copied from rv32zbb.ll and rv64zbb.ll and pruned to what was needed for P. Eventually we should merge these back into a single test file, but I wanted to keep P separated while it is experimental.
1 parent 1e84cb7 commit 17abc16

File tree

7 files changed

+1440
-14
lines changed

7 files changed

+1440
-14
lines changed

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,8 @@ def HasStdExtZbkbOrP
11241124
"'Base P' (Packed-SIMD)">;
11251125

11261126
def HasStdExtZbbOrZbkbOrP
1127-
: Predicate<"Subtarget->HasStdExtZbbOrZbkb()|| Subtarget->hasStdExtP()">,
1127+
: Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbkb() || "
1128+
"Subtarget->hasStdExtP()">,
11281129
AssemblerPredicate<(any_of FeatureStdExtZbb, FeatureStdExtZbkb, FeatureStdExtP),
11291130
"'Zbb' (Basic Bit-Manipulation) or "
11301131
"'Zbkb' (Bitmanip instructions for Cryptography) or "

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
318318

319319
setOperationAction(ISD::EH_DWARF_CFA, MVT::i32, Custom);
320320

321-
if (!Subtarget.hasStdExtZbb() && !Subtarget.hasVendorXTHeadBb() &&
322-
!Subtarget.hasVendorXqcibm() && !Subtarget.hasVendorXAndesPerf() &&
321+
if (!Subtarget.hasStdExtZbb() && !Subtarget.hasStdExtP() &&
322+
!Subtarget.hasVendorXTHeadBb() && !Subtarget.hasVendorXqcibm() &&
323+
!Subtarget.hasVendorXAndesPerf() &&
323324
!(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit()))
324325
setOperationAction(ISD::SIGN_EXTEND_INREG, {MVT::i8, MVT::i16}, Expand);
325326

@@ -392,7 +393,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
392393
setOperationAction(ISD::BITREVERSE, MVT::i8, Custom);
393394
}
394395

395-
if (Subtarget.hasStdExtZbb() ||
396+
if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtP() ||
396397
(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
397398
setOperationAction({ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX}, XLenVT,
398399
Legal);
@@ -403,6 +404,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
403404
setOperationAction({ISD::CTTZ, ISD::CTTZ_ZERO_UNDEF}, MVT::i32, Custom);
404405
} else {
405406
setOperationAction(ISD::CTTZ, XLenVT, Expand);
407+
// If have a CLZW, but not CTZW, custom promote i32.
408+
if (Subtarget.hasStdExtP() && Subtarget.is64Bit())
409+
setOperationAction({ISD::CTTZ, ISD::CTTZ_ZERO_UNDEF}, MVT::i32, Custom);
406410
}
407411

408412
if (!Subtarget.hasCPOPLike()) {
@@ -419,13 +423,15 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
419423
// We need the custom lowering to make sure that the resulting sequence
420424
// for the 32bit case is efficient on 64bit targets.
421425
// Use default promotion for i32 without Zbb.
422-
if (Subtarget.is64Bit() && Subtarget.hasStdExtZbb())
426+
if (Subtarget.is64Bit() &&
427+
(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtP()))
423428
setOperationAction({ISD::CTLZ, ISD::CTLZ_ZERO_UNDEF}, MVT::i32, Custom);
424429
} else {
425430
setOperationAction(ISD::CTLZ, XLenVT, Expand);
426431
}
427432

428-
if (Subtarget.hasVendorXCValu() && !Subtarget.is64Bit()) {
433+
if (Subtarget.hasStdExtP() ||
434+
(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
429435
setOperationAction(ISD::ABS, XLenVT, Legal);
430436
} else if (Subtarget.hasShortForwardBranchOpt()) {
431437
// We can use PseudoCCSUB to implement ABS.
@@ -14669,6 +14675,25 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
1466914675
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(0));
1467014676
bool IsCTZ =
1467114677
N->getOpcode() == ISD::CTTZ || N->getOpcode() == ISD::CTTZ_ZERO_UNDEF;
14678+
14679+
// Without Zbb, lower as 32 - clzw(~X & (X-1))
14680+
if (IsCTZ && !Subtarget.hasStdExtZbb()) {
14681+
assert(Subtarget.hasStdExtP());
14682+
14683+
NewOp0 = DAG.getFreeze(NewOp0);
14684+
SDValue Not = DAG.getNOT(DL, NewOp0, MVT::i64);
14685+
SDValue Minus1 = DAG.getNode(ISD::SUB, DL, MVT::i64, NewOp0,
14686+
DAG.getConstant(1, DL, MVT::i64));
14687+
SDValue And = DAG.getNode(ISD::AND, DL, MVT::i64, Not, Minus1);
14688+
SDValue CLZW = DAG.getNode(RISCVISD::CLZW, DL, MVT::i64, And);
14689+
SDValue Sub = DAG.getNode(ISD::SUB, DL, MVT::i64,
14690+
DAG.getConstant(32, DL, MVT::i64), CLZW);
14691+
SDValue Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i64, Sub,
14692+
DAG.getValueType(MVT::i32));
14693+
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
14694+
return;
14695+
}
14696+
1467214697
unsigned Opc = IsCTZ ? RISCVISD::CTZW : RISCVISD::CLZW;
1467314698
SDValue Res = DAG.getNode(Opc, DL, MVT::i64, NewOp0);
1467414699
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));

llvm/lib/Target/RISCV/RISCVInstrInfoP.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,3 +1455,11 @@ let Predicates = [HasStdExtP, IsRV32] in {
14551455
def PMAXU_DW : RVPPairBinaryExchanged_rr<0b1111, 0b01, "pmaxu.dw">;
14561456
def PMAXU_DB : RVPPairBinaryExchanged_rr<0b1111, 0b10, "pmaxu.db">;
14571457
} // Predicates = [HasStdExtP, IsRV32]
1458+
1459+
1460+
//===----------------------------------------------------------------------===//
1461+
// Codegen patterns
1462+
//===----------------------------------------------------------------------===//
1463+
1464+
let Predicates = [HasStdExtP] in
1465+
def : PatGpr<abs, ABS>;

llvm/lib/Target/RISCV/RISCVInstrInfoZb.td

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -599,37 +599,43 @@ def : PatGpr<riscv_zip, ZIP_RV32, i32>;
599599
def : PatGpr<riscv_unzip, UNZIP_RV32, i32>;
600600
} // Predicates = [HasStdExtZbkb, IsRV32]
601601

602-
let Predicates = [HasStdExtZbb] in {
602+
let Predicates = [HasStdExtZbbOrP] in {
603603
def : PatGpr<ctlz, CLZ>;
604+
}
605+
606+
let Predicates = [HasStdExtZbb] in {
604607
def : PatGpr<cttz, CTZ>;
605608
def : PatGpr<ctpop, CPOP>;
606609
} // Predicates = [HasStdExtZbb]
607610

608-
let Predicates = [HasStdExtZbb, IsRV64] in {
611+
let Predicates = [HasStdExtZbbOrP, IsRV64] in {
609612
def : PatGpr<riscv_clzw, CLZW>;
613+
}
614+
615+
let Predicates = [HasStdExtZbb, IsRV64] in {
610616
def : PatGpr<riscv_ctzw, CTZW>;
611617
def : Pat<(i64 (ctpop (i64 (zexti32 (i64 GPR:$rs1))))), (CPOPW GPR:$rs1)>;
612618

613619
def : Pat<(i64 (riscv_negw_max GPR:$rs1)),
614620
(MAX GPR:$rs1, (XLenVT (SUBW (XLenVT X0), GPR:$rs1)))>;
615621
} // Predicates = [HasStdExtZbb, IsRV64]
616622

617-
let Predicates = [HasStdExtZbb] in {
623+
let Predicates = [HasStdExtZbbOrP] in {
618624
def : Pat<(XLenVT (sext_inreg GPR:$rs1, i8)), (SEXT_B GPR:$rs1)>;
619625
def : Pat<(XLenVT (sext_inreg GPR:$rs1, i16)), (SEXT_H GPR:$rs1)>;
620626
} // Predicates = [HasStdExtZbb]
621627

622-
let Predicates = [HasStdExtZbb] in {
628+
let Predicates = [HasStdExtZbbOrP] in {
623629
def : PatGprGpr<smin, MIN>;
624630
def : PatGprGpr<smax, MAX>;
625631
def : PatGprGpr<umin, MINU>;
626632
def : PatGprGpr<umax, MAXU>;
627633
} // Predicates = [HasStdExtZbb]
628634

629-
let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in
635+
let Predicates = [HasStdExtZbbOrZbkbOrP, IsRV32] in
630636
def : PatGpr<bswap, REV8_RV32, i32>;
631637

632-
let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in
638+
let Predicates = [HasStdExtZbbOrZbkbOrP, IsRV64] in
633639
def : PatGpr<bswap, REV8_RV64, i64>;
634640

635641
let Predicates = [HasStdExtZbkb] in {

llvm/lib/Target/RISCV/RISCVSubtarget.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
187187
}
188188

189189
bool hasCLZLike() const {
190-
return HasStdExtZbb || HasVendorXTHeadBb ||
190+
return HasStdExtZbb || HasStdExtP || HasVendorXTHeadBb ||
191191
(HasVendorXCVbitmanip && !IsRV64);
192192
}
193193
bool hasCTZLike() const {
@@ -197,7 +197,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
197197
return HasStdExtZbb || (HasVendorXCVbitmanip && !IsRV64);
198198
}
199199
bool hasREV8Like() const {
200-
return HasStdExtZbb || HasStdExtZbkb || HasVendorXTHeadBb;
200+
return HasStdExtZbb || HasStdExtZbkb || HasStdExtP || HasVendorXTHeadBb;
201201
}
202202

203203
bool hasBEXTILike() const { return HasStdExtZbs || HasVendorXTHeadBs; }

0 commit comments

Comments
 (0)