Skip to content

Commit 0461448

Browse files
JivanHln8-8
andauthored
[RISCV][ISel] Add ISel support for experimental Zimop extension (#77089)
This implements ISel support for mopr[0-31] and moprr[0-7] instructions for 32 and 64 bits --------- Co-authored-by: ln8-8 <lyut.nersisyan@gmail.com>
1 parent 7855703 commit 0461448

File tree

6 files changed

+226
-0
lines changed

6 files changed

+226
-0
lines changed

llvm/include/llvm/IR/IntrinsicsRISCV.td

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,22 @@ let TargetPrefix = "riscv" in {
108108
def int_riscv_xperm8 : BitManipGPRGPRIntrinsics;
109109
} // TargetPrefix = "riscv"
110110

111+
//===----------------------------------------------------------------------===//
112+
// May-Be-Operations
113+
114+
let TargetPrefix = "riscv" in {
115+
116+
// Zimop
117+
def int_riscv_mopr
118+
: DefaultAttrsIntrinsic<[llvm_any_ty],
119+
[LLVMMatchType<0>, LLVMMatchType<0>],
120+
[IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>]>;
121+
def int_riscv_moprr
122+
: DefaultAttrsIntrinsic<[llvm_any_ty],
123+
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
124+
[IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<2>>]>;
125+
} // TargetPrefix = "riscv"
126+
111127
//===----------------------------------------------------------------------===//
112128
// Vectors
113129

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8575,6 +8575,33 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
85758575
IntNo == Intrinsic::riscv_zip ? RISCVISD::ZIP : RISCVISD::UNZIP;
85768576
return DAG.getNode(Opc, DL, XLenVT, Op.getOperand(1));
85778577
}
8578+
case Intrinsic::riscv_mopr: {
8579+
if (RV64LegalI32 && Subtarget.is64Bit() && Op.getValueType() == MVT::i32) {
8580+
SDValue NewOp =
8581+
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op.getOperand(1));
8582+
SDValue Res = DAG.getNode(
8583+
RISCVISD::MOPR, DL, MVT::i64, NewOp,
8584+
DAG.getTargetConstant(Op.getConstantOperandVal(2), DL, MVT::i64));
8585+
return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res);
8586+
}
8587+
return DAG.getNode(RISCVISD::MOPR, DL, XLenVT, Op.getOperand(1),
8588+
Op.getOperand(2));
8589+
}
8590+
8591+
case Intrinsic::riscv_moprr: {
8592+
if (RV64LegalI32 && Subtarget.is64Bit() && Op.getValueType() == MVT::i32) {
8593+
SDValue NewOp0 =
8594+
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op.getOperand(1));
8595+
SDValue NewOp1 =
8596+
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op.getOperand(2));
8597+
SDValue Res = DAG.getNode(
8598+
RISCVISD::MOPRR, DL, MVT::i64, NewOp0, NewOp1,
8599+
DAG.getTargetConstant(Op.getConstantOperandVal(3), DL, MVT::i64));
8600+
return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res);
8601+
}
8602+
return DAG.getNode(RISCVISD::MOPRR, DL, XLenVT, Op.getOperand(1),
8603+
Op.getOperand(2), Op.getOperand(3));
8604+
}
85788605
case Intrinsic::riscv_clmul:
85798606
if (RV64LegalI32 && Subtarget.is64Bit() && Op.getValueType() == MVT::i32) {
85808607
SDValue NewOp0 =
@@ -11956,6 +11983,30 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
1195611983
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
1195711984
return;
1195811985
}
11986+
case Intrinsic::riscv_mopr: {
11987+
if (!Subtarget.is64Bit() || N->getValueType(0) != MVT::i32)
11988+
return;
11989+
SDValue NewOp =
11990+
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1));
11991+
SDValue Res = DAG.getNode(
11992+
RISCVISD::MOPR, DL, MVT::i64, NewOp,
11993+
DAG.getTargetConstant(N->getConstantOperandVal(2), DL, MVT::i64));
11994+
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
11995+
return;
11996+
}
11997+
case Intrinsic::riscv_moprr: {
11998+
if (!Subtarget.is64Bit() || N->getValueType(0) != MVT::i32)
11999+
return;
12000+
SDValue NewOp0 =
12001+
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1));
12002+
SDValue NewOp1 =
12003+
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(2));
12004+
SDValue Res = DAG.getNode(
12005+
RISCVISD::MOPRR, DL, MVT::i64, NewOp0, NewOp1,
12006+
DAG.getTargetConstant(N->getConstantOperandVal(3), DL, MVT::i64));
12007+
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
12008+
return;
12009+
}
1195912010
case Intrinsic::riscv_clmul: {
1196012011
if (!Subtarget.is64Bit() || N->getValueType(0) != MVT::i32)
1196112012
return;
@@ -18916,6 +18967,8 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
1891618967
NODE_NAME_CASE(CLMUL)
1891718968
NODE_NAME_CASE(CLMULH)
1891818969
NODE_NAME_CASE(CLMULR)
18970+
NODE_NAME_CASE(MOPR)
18971+
NODE_NAME_CASE(MOPRR)
1891918972
NODE_NAME_CASE(SHA256SIG0)
1892018973
NODE_NAME_CASE(SHA256SIG1)
1892118974
NODE_NAME_CASE(SHA256SUM0)

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ enum NodeType : unsigned {
142142
SM4KS, SM4ED,
143143
SM3P0, SM3P1,
144144

145+
// May-Be-Operations
146+
MOPR, MOPRR,
147+
145148
// Vector Extension
146149
FIRST_VL_VECTOR_OP,
147150
// VMV_V_V_VL matches the semantics of vmv.v.v but includes an extra operand

llvm/lib/Target/RISCV/RISCVInstrInfoZimop.td

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ class RVInstRMoprr<bits<4> imm4, bits<3> imm3, bits<3> funct3, RISCVOpcode opcod
3434
let Inst{25} = imm4{0};
3535
}
3636

37+
def riscv_mopr : SDNode<"RISCVISD::MOPR",
38+
SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
39+
SDTCisSameAs<0, 2>]>>;
40+
def riscv_moprr : SDNode<"RISCVISD::MOPRR",
41+
SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
42+
SDTCisSameAs<0, 2>,
43+
SDTCisSameAs<0, 3>]>>;
44+
3745
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
3846
class RVMopr<bits<7> imm7, bits<5> imm5, bits<3> funct3,
3947
RISCVOpcode opcode, string opcodestr>
@@ -57,3 +65,17 @@ foreach i = 0...7 in {
5765
def MOPRR#i : RVMoprr<0b1001, i, 0b100, OPC_SYSTEM, "mop.rr."#i>,
5866
Sched<[]>;
5967
}
68+
69+
let Predicates = [HasStdExtZimop] in {
70+
// Zimop instructions
71+
foreach i = 0...31 in {
72+
def : Pat<(XLenVT (riscv_mopr GPR:$rs1, (XLenVT i))),
73+
(!cast<Instruction>("MOPR"#i) GPR:$rs1)>;
74+
}
75+
76+
foreach i = 0...7 in {
77+
def : Pat<(XLenVT (riscv_moprr GPR:$rs1, GPR:$rs2, (XLenVT i))),
78+
(!cast<Instruction>("MOPRR"#i) GPR:$rs1, GPR:$rs2)>;
79+
}
80+
81+
} // Predicates = [HasStdExtZimop]
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zimop -verify-machineinstrs < %s \
3+
; RUN: | FileCheck %s -check-prefix=RV32ZIMOP
4+
5+
declare i32 @llvm.riscv.mopr.i32(i32 %a, i32 %b)
6+
7+
define i32 @mopr0_32(i32 %a) nounwind {
8+
; RV32ZIMOP-LABEL: mopr0_32:
9+
; RV32ZIMOP: # %bb.0:
10+
; RV32ZIMOP-NEXT: mop.r.0 a0, a0
11+
; RV32ZIMOP-NEXT: ret
12+
%tmp = call i32 @llvm.riscv.mopr.i32(i32 %a, i32 0)
13+
ret i32 %tmp
14+
}
15+
16+
define i32 @mopr31_32(i32 %a) nounwind {
17+
; RV32ZIMOP-LABEL: mopr31_32:
18+
; RV32ZIMOP: # %bb.0:
19+
; RV32ZIMOP-NEXT: mop.r.31 a0, a0
20+
; RV32ZIMOP-NEXT: ret
21+
%tmp = call i32 @llvm.riscv.mopr.i32(i32 %a, i32 31)
22+
ret i32 %tmp
23+
}
24+
25+
declare i32 @llvm.riscv.moprr.i32(i32 %a, i32 %b, i32 %c)
26+
27+
define i32 @moprr0_32(i32 %a, i32 %b) nounwind {
28+
; RV32ZIMOP-LABEL: moprr0_32:
29+
; RV32ZIMOP: # %bb.0:
30+
; RV32ZIMOP-NEXT: mop.rr.0 a0, a0, a1
31+
; RV32ZIMOP-NEXT: ret
32+
%tmp = call i32 @llvm.riscv.moprr.i32(i32 %a, i32 %b, i32 0)
33+
ret i32 %tmp
34+
}
35+
36+
define i32 @moprr7_32(i32 %a, i32 %b) nounwind {
37+
; RV32ZIMOP-LABEL: moprr7_32:
38+
; RV32ZIMOP: # %bb.0:
39+
; RV32ZIMOP-NEXT: mop.rr.7 a0, a0, a1
40+
; RV32ZIMOP-NEXT: ret
41+
%tmp = call i32 @llvm.riscv.moprr.i32(i32 %a, i32 %b, i32 7)
42+
ret i32 %tmp
43+
}
44+
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zimop -verify-machineinstrs < %s \
3+
; RUN: | FileCheck %s -check-prefix=RV64ZIMOP
4+
5+
declare i64 @llvm.riscv.mopr.i64(i64 %a, i64 %b)
6+
7+
define i64 @mopr0_64(i64 %a) nounwind {
8+
; RV64ZIMOP-LABEL: mopr0_64:
9+
; RV64ZIMOP: # %bb.0:
10+
; RV64ZIMOP-NEXT: mop.r.0 a0, a0
11+
; RV64ZIMOP-NEXT: ret
12+
%tmp = call i64 @llvm.riscv.mopr.i64(i64 %a, i64 0)
13+
ret i64 %tmp
14+
}
15+
16+
define i64 @mopr31_64(i64 %a) nounwind {
17+
; RV64ZIMOP-LABEL: mopr31_64:
18+
; RV64ZIMOP: # %bb.0:
19+
; RV64ZIMOP-NEXT: mop.r.31 a0, a0
20+
; RV64ZIMOP-NEXT: ret
21+
%tmp = call i64 @llvm.riscv.mopr.i64(i64 %a, i64 31)
22+
ret i64 %tmp
23+
}
24+
25+
declare i64 @llvm.riscv.moprr.i64(i64 %a, i64 %b, i64 %c)
26+
27+
define i64 @moprr0_64(i64 %a, i64 %b) nounwind {
28+
; RV64ZIMOP-LABEL: moprr0_64:
29+
; RV64ZIMOP: # %bb.0:
30+
; RV64ZIMOP-NEXT: mop.rr.0 a0, a0, a1
31+
; RV64ZIMOP-NEXT: ret
32+
%tmp = call i64 @llvm.riscv.moprr.i64(i64 %a, i64 %b, i64 0)
33+
ret i64 %tmp
34+
}
35+
36+
define i64 @moprr7_64(i64 %a, i64 %b) nounwind {
37+
; RV64ZIMOP-LABEL: moprr7_64:
38+
; RV64ZIMOP: # %bb.0:
39+
; RV64ZIMOP-NEXT: mop.rr.7 a0, a0, a1
40+
; RV64ZIMOP-NEXT: ret
41+
%tmp = call i64 @llvm.riscv.moprr.i64(i64 %a, i64 %b, i64 7)
42+
ret i64 %tmp
43+
}
44+
45+
declare i32 @llvm.riscv.mopr.i32(i32 %a, i32 %b)
46+
47+
define signext i32 @mopr0_32(i32 signext %a) nounwind {
48+
; RV64ZIMOP-LABEL: mopr0_32:
49+
; RV64ZIMOP: # %bb.0:
50+
; RV64ZIMOP-NEXT: mop.r.0 a0, a0
51+
; RV64ZIMOP-NEXT: sext.w a0, a0
52+
; RV64ZIMOP-NEXT: ret
53+
%tmp = call i32 @llvm.riscv.mopr.i32(i32 %a, i32 0)
54+
ret i32 %tmp
55+
}
56+
57+
define signext i32 @mopr31_32(i32 signext %a) nounwind {
58+
; RV64ZIMOP-LABEL: mopr31_32:
59+
; RV64ZIMOP: # %bb.0:
60+
; RV64ZIMOP-NEXT: mop.r.31 a0, a0
61+
; RV64ZIMOP-NEXT: sext.w a0, a0
62+
; RV64ZIMOP-NEXT: ret
63+
%tmp = call i32 @llvm.riscv.mopr.i32(i32 %a, i32 31)
64+
ret i32 %tmp
65+
}
66+
67+
declare i32 @llvm.riscv.moprr.i32(i32 %a, i32 %b, i32 %c)
68+
69+
define signext i32 @moprr0_32(i32 signext %a, i32 signext %b) nounwind {
70+
; RV64ZIMOP-LABEL: moprr0_32:
71+
; RV64ZIMOP: # %bb.0:
72+
; RV64ZIMOP-NEXT: mop.rr.0 a0, a0, a1
73+
; RV64ZIMOP-NEXT: sext.w a0, a0
74+
; RV64ZIMOP-NEXT: ret
75+
%tmp = call i32 @llvm.riscv.moprr.i32(i32 %a, i32 %b, i32 0)
76+
ret i32 %tmp
77+
}
78+
79+
define signext i32 @moprr7_32(i32 signext %a, i32 signext %b) nounwind {
80+
; RV64ZIMOP-LABEL: moprr7_32:
81+
; RV64ZIMOP: # %bb.0:
82+
; RV64ZIMOP-NEXT: mop.rr.7 a0, a0, a1
83+
; RV64ZIMOP-NEXT: sext.w a0, a0
84+
; RV64ZIMOP-NEXT: ret
85+
%tmp = call i32 @llvm.riscv.moprr.i32(i32 %a, i32 %b, i32 7)
86+
ret i32 %tmp
87+
}
88+

0 commit comments

Comments
 (0)