Skip to content

Commit 437d6e0

Browse files
committed
[RISCV] Implement Intrinsics and CodeGen Support for XCValu Extension in CV32E40P
Implement XCValu intrinsics for CV32E40P according to the specification. This commit is part of a patch-set to upstream the vendor specific extensions of CV32E40P that need LLVM intrinsics to implement Clang builtins. Contributors: @CharKeaney, @ChunyuLiao, @jeremybennett, @lewis-revill, @NandniJamnadas, @PaoloS02, @serkm, @simonpcook, @xingmingjie.
1 parent 6752f15 commit 437d6e0

File tree

5 files changed

+780
-7
lines changed

5 files changed

+780
-7
lines changed

llvm/include/llvm/IR/IntrinsicsRISCVXCV.td

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ class ScalarCoreVBitManipGprIntrinsic
1818
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty],
1919
[IntrNoMem, IntrSpeculatable]>;
2020

21+
class ScalarCoreVAluGprIntrinsic
22+
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty],
23+
[IntrNoMem, IntrSpeculatable]>;
24+
25+
class ScalarCoreVAluGprGprIntrinsic
26+
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
27+
[IntrNoMem, IntrSpeculatable]>;
28+
29+
class ScalarCoreVAluGprGprGprIntrinsic
30+
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
31+
[IntrNoMem, IntrSpeculatable]>;
32+
2133
let TargetPrefix = "riscv" in {
2234
def int_riscv_cv_bitmanip_extract : ScalarCoreVBitManipGprGprIntrinsic;
2335
def int_riscv_cv_bitmanip_extractu : ScalarCoreVBitManipGprGprIntrinsic;
@@ -34,4 +46,20 @@ let TargetPrefix = "riscv" in {
3446
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
3547
[IntrNoMem, IntrWillReturn, IntrSpeculatable,
3648
ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
49+
50+
def int_riscv_cv_alu_exths : ScalarCoreVAluGprIntrinsic;
51+
def int_riscv_cv_alu_exthz : ScalarCoreVAluGprIntrinsic;
52+
def int_riscv_cv_alu_extbs : ScalarCoreVAluGprIntrinsic;
53+
def int_riscv_cv_alu_extbz : ScalarCoreVAluGprIntrinsic;
54+
55+
def int_riscv_cv_alu_clip : ScalarCoreVAluGprGprIntrinsic;
56+
def int_riscv_cv_alu_clipu : ScalarCoreVAluGprGprIntrinsic;
57+
def int_riscv_cv_alu_addn : ScalarCoreVAluGprGprGprIntrinsic;
58+
def int_riscv_cv_alu_addun : ScalarCoreVAluGprGprGprIntrinsic;
59+
def int_riscv_cv_alu_addrn : ScalarCoreVAluGprGprGprIntrinsic;
60+
def int_riscv_cv_alu_addurn : ScalarCoreVAluGprGprGprIntrinsic;
61+
def int_riscv_cv_alu_subn : ScalarCoreVAluGprGprGprIntrinsic;
62+
def int_riscv_cv_alu_subun : ScalarCoreVAluGprGprGprIntrinsic;
63+
def int_riscv_cv_alu_subrn : ScalarCoreVAluGprGprGprIntrinsic;
64+
def int_riscv_cv_alu_suburn : ScalarCoreVAluGprGprGprIntrinsic;
3765
} // TargetPrefix = "riscv"

llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,6 @@ bool RISCVPreRAExpandPseudo::expandLoadTLSGDAddress(
546546
return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GD_HI,
547547
RISCV::ADDI);
548548
}
549-
550549
} // end of anonymous namespace
551550

552551
INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo",

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,12 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
250250
if (RV64LegalI32 && Subtarget.is64Bit())
251251
setOperationAction(ISD::SELECT_CC, MVT::i32, Expand);
252252

253-
setCondCodeAction(ISD::SETLE, XLenVT, Expand);
253+
if (!Subtarget.hasVendorXCValu())
254+
setCondCodeAction(ISD::SETLE, XLenVT, Expand);
254255
setCondCodeAction(ISD::SETGT, XLenVT, Custom);
255256
setCondCodeAction(ISD::SETGE, XLenVT, Expand);
256-
setCondCodeAction(ISD::SETULE, XLenVT, Expand);
257+
if (!Subtarget.hasVendorXCValu())
258+
setCondCodeAction(ISD::SETULE, XLenVT, Expand);
257259
setCondCodeAction(ISD::SETUGT, XLenVT, Custom);
258260
setCondCodeAction(ISD::SETUGE, XLenVT, Expand);
259261

@@ -1366,6 +1368,16 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
13661368
}
13671369
}
13681370

1371+
if (Subtarget.hasVendorXCValu()) {
1372+
setOperationAction(ISD::ABS, XLenVT, Legal);
1373+
setOperationAction(ISD::SMIN, XLenVT, Legal);
1374+
setOperationAction(ISD::UMIN, XLenVT, Legal);
1375+
setOperationAction(ISD::SMAX, XLenVT, Legal);
1376+
setOperationAction(ISD::UMAX, XLenVT, Legal);
1377+
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Legal);
1378+
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Legal);
1379+
}
1380+
13691381
// Function alignments.
13701382
const Align FunctionAlignment(Subtarget.hasStdExtCOrZca() ? 2 : 4);
13711383
setMinFunctionAlignment(FunctionAlignment);

llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td

Lines changed: 155 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ let DecoderNamespace = "XCValu" in {
198198

199199
} // DecoderNamespace = "XCValu"
200200

201-
let Predicates = [HasVendorXCValu],
201+
let Predicates = [HasVendorXCValu, IsRV32],
202202
hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
203203
// General ALU Operations
204204
def CV_ABS : CVInstAluR<0b0101000, 0b011, "cv.abs">,
@@ -249,10 +249,10 @@ let Predicates = [HasVendorXCValu],
249249
Sched<[]>;
250250
def CV_SUBURN : CVInstAluRRI<0b11, 0b011, "cv.suburn">,
251251
Sched<[]>;
252-
} // Predicates = [HasVendorXCValu],
252+
} // Predicates = [HasVendorXCValu, IsRV32],
253253
// hasSideEffects = 0, mayLoad = 0, mayStore = 0
254254

255-
let Predicates = [HasVendorXCValu],
255+
let Predicates = [HasVendorXCValu, IsRV32],
256256
hasSideEffects = 0, mayLoad = 0, mayStore = 0,
257257
Constraints = "$rd = $rd_wb" in {
258258
def CV_ADDNR : CVInstAluRRNR<0b1000000, 0b011, "cv.addnr">,
@@ -272,7 +272,7 @@ let Predicates = [HasVendorXCValu],
272272
def CV_SUBURNR : CVInstAluRRNR<0b1000111, 0b011, "cv.suburnr">,
273273
Sched<[]>;
274274

275-
} // Predicates = [HasVendorXCValu],
275+
} // Predicates = [HasVendorXCValu, IsRV32],
276276
// hasSideEffects = 0, mayLoad = 0, mayStore = 0,
277277
// Constraints = "$rd = $rd_wb"
278278

@@ -662,6 +662,8 @@ let Predicates = [HasVendorXCVelw, IsRV32], hasSideEffects = 0,
662662
def cv_tuimm2 : TImmLeaf<XLenVT, [{return isUInt<2>(Imm);}]>;
663663
def cv_tuimm5 : TImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]>;
664664
def cv_uimm10 : ImmLeaf<XLenVT, [{return isUInt<10>(Imm);}]>;
665+
def cv_uimm_pow2: Operand<XLenVT>,
666+
ImmLeaf<XLenVT, [{return isPowerOf2_32(Imm + 1);}]>;
665667

666668
def CV_LO5: SDNodeXForm<imm, [{
667669
return CurDAG->getTargetConstant(N->getZExtValue() & 0x1f, SDLoc(N),
@@ -673,6 +675,49 @@ def CV_HI5: SDNodeXForm<imm, [{
673675
N->getValueType(0));
674676
}]>;
675677

678+
def between : PatFrags<(ops node:$lowerBound, node:$upperBound, node:$value),
679+
[(smin (smax node:$value, node:$lowerBound), node:$upperBound),
680+
(smax (smin node:$value, node:$upperBound), node:$lowerBound)]>;
681+
682+
def betweenu : PatFrags<(ops node:$upperBound, node:$value),
683+
[(smin (smax node:$value, 0), node:$upperBound),
684+
(smax (smin node:$value, node:$upperBound), 0)]>;
685+
def powerOf2 : ImmLeaf<XLenVT, [{ return isPowerOf2_32(Imm); }]>;
686+
def powerOf2Minus1 : ImmLeaf<XLenVT, [{ return isPowerOf2_32(Imm+1); }]>;
687+
def negativePowerOf2 : ImmLeaf<XLenVT, [{ return isPowerOf2_32(-Imm); }]>;
688+
def roundBit : PatFrag<(ops node:$shiftAmount),
689+
(srl (shl 1, node:$shiftAmount), (XLenVT 1))>;
690+
def trailing1sPlus1 : SDNodeXForm<imm, [{
691+
return CurDAG->getTargetConstant(
692+
llvm::countr_one(N->getZExtValue()) + 1,
693+
SDLoc(N), N->getValueType(0));
694+
}]>;
695+
696+
def shiftRound : PatFrag<(ops node:$value, node:$shiftAmount),
697+
(sra (add node:$value, powerOf2), node:$shiftAmount), [{
698+
if (auto powerOf2 = dyn_cast<ConstantSDNode>(N->getOperand(0)->getOperand(1)))
699+
return (powerOf2->getZExtValue() << 1) == (1U << N->getConstantOperandVal(1));
700+
return false;
701+
}]>;
702+
703+
def ushiftRound : PatFrag<(ops node:$value, node:$shiftAmount),
704+
(srl (add node:$value, powerOf2), node:$shiftAmount), [{
705+
if (auto powerOf2 = dyn_cast<ConstantSDNode>(N->getOperand(0)->getOperand(1)))
706+
return (powerOf2->getZExtValue() << 1) == (1U << N->getConstantOperandVal(1));
707+
return false;
708+
}]>;
709+
710+
def clip : PatFrag<(ops node:$upperBound, node:$value),
711+
(between negativePowerOf2, node:$upperBound, node:$value), [{
712+
// Checking lower & upper bound for the clip instruction
713+
if (auto bound1 = dyn_cast<ConstantSDNode>(N->getOperand(0)->getOperand(1))) {
714+
if (auto bound2 = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
715+
return (bound1->getSExtValue() == ~bound2->getSExtValue());
716+
}
717+
}
718+
return false;
719+
}]>;
720+
676721
multiclass PatCoreVBitManip<Intrinsic intr> {
677722
def : PatGprGpr<intr, !cast<RVInst>("CV_" # NAME # "R")>;
678723
def : Pat<(intr GPR:$rs1, cv_uimm10:$imm),
@@ -704,3 +749,109 @@ let Predicates = [HasVendorXCVbitmanip, IsRV32] in {
704749
(CV_BITREV GPR:$rs1, cv_tuimm2:$radix, cv_tuimm5:$pts)>;
705750
def : Pat<(bitreverse (XLenVT GPR:$rs)), (CV_BITREV GPR:$rs, 0, 0)>;
706751
}
752+
753+
class PatCoreVAluGpr <string intr, string asm> :
754+
PatGpr<!cast<Intrinsic>("int_riscv_cv_alu_" # intr),
755+
!cast<RVInst>("CV_" # asm)>;
756+
class PatCoreVAluGprGpr <string intr, string asm> :
757+
PatGprGpr<!cast<Intrinsic>("int_riscv_cv_alu_" # intr),
758+
!cast<RVInst>("CV_" # asm)>;
759+
760+
multiclass PatCoreVAluGprImm <Intrinsic intr> {
761+
def : PatGprGpr<intr, !cast<RVInst>("CV_" # NAME # "R")>;
762+
def : Pat<(intr (XLenVT GPR:$rs1), powerOf2Minus1:$upperBound),
763+
(!cast<RVInst>("CV_" # NAME) GPR:$rs1,
764+
(trailing1sPlus1 imm:$upperBound))>;
765+
}
766+
767+
multiclass PatCoreVAluGprGprImm <Intrinsic intr> {
768+
def : Pat<(intr GPR:$rs1, GPR:$rs2, GPR:$rs3),
769+
(!cast<RVInst>("CV_" # NAME # "R") GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
770+
def : Pat<(intr GPR:$rs1, GPR:$rs2, uimm5:$imm),
771+
(!cast<RVInst>("CV_" # NAME) GPR:$rs1, GPR:$rs2, uimm5:$imm)>;
772+
}
773+
774+
let Predicates = [HasVendorXCValu, IsRV32], AddedComplexity = 1 in {
775+
def : PatGpr<abs, CV_ABS>;
776+
def : PatGprGpr<setle, CV_SLET>;
777+
def : PatGprGpr<setule, CV_SLETU>;
778+
def : PatGprGpr<smin, CV_MIN>;
779+
def : PatGprGpr<umin, CV_MINU>;
780+
def : PatGprGpr<smax, CV_MAX>;
781+
def : PatGprGpr<umax, CV_MAXU>;
782+
783+
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (CV_EXTHS GPR:$rs1)>;
784+
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (CV_EXTBS GPR:$rs1)>;
785+
786+
def : Pat<(and (XLenVT GPR:$rs1), 0xffff), (CV_EXTHZ GPR:$rs1)>;
787+
def : Pat<(and (XLenVT GPR:$rs1), 0xff), (CV_EXTBZ GPR:$rs1)>;
788+
789+
def : Pat<(clip powerOf2Minus1:$upperBound, (XLenVT GPR:$rs1)),
790+
(CV_CLIP GPR:$rs1, (trailing1sPlus1 imm:$upperBound))>;
791+
def : Pat<(between (not GPR:$rs2), GPR:$rs2, (XLenVT GPR:$rs1)),
792+
(CV_CLIPR GPR:$rs1, GPR:$rs2)>;
793+
def : Pat<(betweenu powerOf2Minus1:$upperBound, (XLenVT GPR:$rs1)),
794+
(CV_CLIPU GPR:$rs1, (trailing1sPlus1 imm:$upperBound))>;
795+
def : Pat<(betweenu GPR:$rs2, (XLenVT GPR:$rs1)),
796+
(CV_CLIPUR GPR:$rs1, GPR:$rs2)>;
797+
798+
def : Pat<(sra (add (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)), uimm5:$imm5),
799+
(CV_ADDN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
800+
def : Pat<(srl (add (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)), uimm5:$imm5),
801+
(CV_ADDUN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
802+
def : Pat<(shiftRound (add (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)),
803+
uimm5:$imm5),
804+
(CV_ADDRN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
805+
def : Pat<(ushiftRound (add (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)),
806+
uimm5:$imm5),
807+
(CV_ADDURN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
808+
809+
def : Pat<(sra (sub (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)), uimm5:$imm5),
810+
(CV_SUBN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
811+
def : Pat<(srl (sub (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)), uimm5:$imm5),
812+
(CV_SUBUN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
813+
def : Pat<(shiftRound (sub (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)),
814+
uimm5:$imm5),
815+
(CV_SUBRN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
816+
def : Pat<(ushiftRound (sub (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)),
817+
uimm5:$imm5),
818+
(CV_SUBURN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
819+
820+
def : Pat<(sra (add (XLenVT GPR:$rd), (XLenVT GPR:$rs1)), (XLenVT GPR:$rs2)),
821+
(CV_ADDNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
822+
def : Pat<(srl (add (XLenVT GPR:$rd), (XLenVT GPR:$rs1)), (XLenVT GPR:$rs2)),
823+
(CV_ADDUNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
824+
def : Pat<(sra (add (add (XLenVT GPR:$rd), (XLenVT GPR:$rs1)),
825+
(roundBit (XLenVT GPR:$rs2))), (XLenVT GPR:$rs2)),
826+
(CV_ADDRNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
827+
def : Pat<(srl (add (add (XLenVT GPR:$rd), (XLenVT GPR:$rs1)),
828+
(roundBit (XLenVT GPR:$rs2))), (XLenVT GPR:$rs2)),
829+
(CV_ADDURNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
830+
831+
def : Pat<(sra (sub (XLenVT GPR:$rd), (XLenVT GPR:$rs1)), (XLenVT GPR:$rs2)),
832+
(CV_SUBNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
833+
def : Pat<(srl (sub (XLenVT GPR:$rd), (XLenVT GPR:$rs1)), (XLenVT GPR:$rs2)),
834+
(CV_SUBUNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
835+
def : Pat<(sra (add (sub (XLenVT GPR:$rd), (XLenVT GPR:$rs1)),
836+
(roundBit (XLenVT GPR:$rs2))), (XLenVT GPR:$rs2)),
837+
(CV_SUBRNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
838+
def : Pat<(srl (add (sub (XLenVT GPR:$rd), (XLenVT GPR:$rs1)),
839+
(roundBit (XLenVT GPR:$rs2))), (XLenVT GPR:$rs2)),
840+
(CV_SUBURNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
841+
842+
def : PatCoreVAluGpr<"exths", "EXTHS">;
843+
def : PatCoreVAluGpr<"exthz", "EXTHZ">;
844+
def : PatCoreVAluGpr<"extbs", "EXTBS">;
845+
def : PatCoreVAluGpr<"extbz", "EXTBZ">;
846+
847+
defm CLIP : PatCoreVAluGprImm<int_riscv_cv_alu_clip>;
848+
defm CLIPU : PatCoreVAluGprImm<int_riscv_cv_alu_clipu>;
849+
defm ADDN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addn>;
850+
defm ADDUN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addun>;
851+
defm ADDRN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addrn>;
852+
defm ADDURN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addurn>;
853+
defm SUBN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subn>;
854+
defm SUBUN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subun>;
855+
defm SUBRN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subrn>;
856+
defm SUBURN : PatCoreVAluGprGprImm<int_riscv_cv_alu_suburn>;
857+
} // Predicates = [HasVendorXCValu, IsRV32]

0 commit comments

Comments
 (0)