From c8c9023284759150fa1ca70442d8c2c6d33ba040 Mon Sep 17 00:00:00 2001 From: Qihan Cai <qcai8733@uni.sydney.edu.au> Date: Fri, 26 May 2023 12:46:35 +1000 Subject: [PATCH] [RISCV][CodeGen] Implement XcvMac Intrinsics Implement XcvMac intrinsics in CodeGen. Spec: https://github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md --- llvm/include/llvm/IR/IntrinsicsRISCV.td | 33 +++ llvm/lib/Support/RISCVISAInfo.cpp | 1 + llvm/lib/Target/RISCV/RISCVInstrInfoCOREV.td | 31 ++- llvm/test/CodeGen/RISCV/corev/mac.ll | 208 +++++++++++++++++++ 4 files changed, 272 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index 5ced421c0a44..5e0b91da5661 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -1735,4 +1735,37 @@ def int_riscv_cv_bitmanip_ror : ScalarCoreVBitManipGprGprIntrinsic; def int_riscv_cv_bitmanip_bitrev : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrWillReturn, IntrSpeculatable, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>; + +class ScalarCoreVMacGprGprGprIntrinsic + : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrWillReturn, IntrSpeculatable]>; + +class ScalarCoreVMacGprGPRImmIntrinsic + : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrWillReturn, IntrSpeculatable, ImmArg<ArgIndex<2>>]>; + +class ScalarCoreVMacGprGprGprImmIntrinsic + : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrWillReturn, IntrSpeculatable, ImmArg<ArgIndex<3>>]>; + +def int_riscv_cv_mac_mac : ScalarCoreVMacGprGprGprIntrinsic; +def int_riscv_cv_mac_msu : ScalarCoreVMacGprGprGprIntrinsic; + +def int_riscv_cv_mac_mulun : ScalarCoreVMacGprGPRImmIntrinsic; +def int_riscv_cv_mac_mulhhun : ScalarCoreVMacGprGPRImmIntrinsic; +def int_riscv_cv_mac_mulsn : ScalarCoreVMacGprGPRImmIntrinsic; +def int_riscv_cv_mac_mulhhsn : ScalarCoreVMacGprGPRImmIntrinsic; +def int_riscv_cv_mac_mulurn : ScalarCoreVMacGprGPRImmIntrinsic; +def int_riscv_cv_mac_mulhhurn : ScalarCoreVMacGprGPRImmIntrinsic; +def int_riscv_cv_mac_mulsrn : ScalarCoreVMacGprGPRImmIntrinsic; +def int_riscv_cv_mac_mulhhsrn : ScalarCoreVMacGprGPRImmIntrinsic; + +def int_riscv_cv_mac_macun : ScalarCoreVMacGprGprGprImmIntrinsic; +def int_riscv_cv_mac_machhun : ScalarCoreVMacGprGprGprImmIntrinsic; +def int_riscv_cv_mac_macsn : ScalarCoreVMacGprGprGprImmIntrinsic; +def int_riscv_cv_mac_machhsn : ScalarCoreVMacGprGprGprImmIntrinsic; +def int_riscv_cv_mac_macurn : ScalarCoreVMacGprGprGprImmIntrinsic; +def int_riscv_cv_mac_machhurn : ScalarCoreVMacGprGprGprImmIntrinsic; +def int_riscv_cv_mac_macsrn : ScalarCoreVMacGprGprGprImmIntrinsic; +def int_riscv_cv_mac_machhsrn : ScalarCoreVMacGprGprGprImmIntrinsic; } // TargetPrefix = "riscv" diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp index 92616d467174..d30ca58acbd8 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -107,6 +107,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = { {"xcvsimd", RISCVExtensionVersion{1, 0}}, {"xcvbitmanip", RISCVExtensionVersion{1, 0}}, {"xcvbi", RISCVExtensionVersion{1, 0}}, + {"xcvmac", RISCVExtensionVersion{1, 0}} }; static const RISCVSupportedExtension SupportedExperimentalExtensions[] = { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoCOREV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoCOREV.td index d3edf15729a0..2f65ca68aea2 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoCOREV.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoCOREV.td @@ -707,6 +707,15 @@ def trailing1sPlus1 : SDNodeXForm<imm, [{ // Patterns for MAC operations //===----------------------------------------------------------------------===// +class PatCoreVMacGprGprGpr <string intr, string asm> + : Pat<(!cast<Intrinsic>("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd), + (!cast<RVInst>("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2)>; +class PatCoreVMacGprGprGprUimm5 <string intr, string asm> + : Pat<(!cast<Intrinsic>("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd, cv_tuimm5:$imm5), + (!cast<RVInst>("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5)>; +class PatCoreVMacGprGprUimm5 <string intr, string asm> + : Pat<(!cast<Intrinsic>("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5), + (!cast<RVInst>("CV_" # asm) GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5)>; let Predicates = [HasExtXcvmac] in { @@ -759,6 +768,26 @@ let Predicates = [HasExtXcvmac] in { def : Pat<(ushiftRound (machhu GPR:$rd, GPR:$rs1, GPR:$rs2), uimm5:$imm5), (CV_MACHHURN GPR:$rd, GPR:$rs1, GPR:$rs2, uimm5:$imm5)>; + def : PatCoreVMacGprGprGpr<"mac", "MAC">; + def : PatCoreVMacGprGprGpr<"msu", "MSU">; + + def : PatCoreVMacGprGprUimm5<"mulun", "MULUN">; + def : PatCoreVMacGprGprUimm5<"mulhhun", "MULHHUN">; + def : PatCoreVMacGprGprUimm5<"mulsn", "MULSN">; + def : PatCoreVMacGprGprUimm5<"mulhhsn", "MULHHSN">; + def : PatCoreVMacGprGprUimm5<"mulurn", "MULURN">; + def : PatCoreVMacGprGprUimm5<"mulhhurn", "MULHHURN">; + def : PatCoreVMacGprGprUimm5<"mulsrn", "MULSRN">; + def : PatCoreVMacGprGprUimm5<"mulhhsrn", "MULHHSRN">; + + def : PatCoreVMacGprGprGprUimm5<"macun", "MACUN">; + def : PatCoreVMacGprGprGprUimm5<"machhun", "MACHHUN">; + def : PatCoreVMacGprGprGprUimm5<"macsn", "MACSN">; + def : PatCoreVMacGprGprGprUimm5<"machhsn", "MACHHSN">; + def : PatCoreVMacGprGprGprUimm5<"macurn", "MACURN">; + def : PatCoreVMacGprGprGprUimm5<"machhurn", "MACHHURN">; + def : PatCoreVMacGprGprGprUimm5<"macsrn", "MACSRN">; + def : PatCoreVMacGprGprGprUimm5<"machhsrn", "MACHHSRN">; } //===----------------------------------------------------------------------===// @@ -887,7 +916,7 @@ let Predicates = [HasExtXcvmem] in { //===----------------------------------------------------------------------===// class PatCorevGprGpr <string intr, string asm> : - PatGprGpr<!cast<Intrinsic>("int_riscv_cv_simd_" # intr), + PatGprGpr<!cast<Intrinsic>("int_riscv_cv_simd_" # intr), !cast<RVInst>("CV_" # asm)>; // Note that rd is the last argument diff --git a/llvm/test/CodeGen/RISCV/corev/mac.ll b/llvm/test/CodeGen/RISCV/corev/mac.ll index 334e8ad0e1ef..430437f00780 100644 --- a/llvm/test/CodeGen/RISCV/corev/mac.ll +++ b/llvm/test/CodeGen/RISCV/corev/mac.ll @@ -306,3 +306,211 @@ define i32 @machhuRN(i32 %a, i32 %b, i32 %c) { %6 = lshr i32 %5, 5 ret i32 %6 } + +declare i32 @llvm.riscv.cv.mac.mac(i32, i32, i32) + +define i32 @test.mac(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: test.mac: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.mac a2, a0, a1 +; CHECK-NEXT: mv a0, a2 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.mac(i32 %a, i32 %b, i32 %c) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.msu(i32, i32, i32) + +define i32 @test.msu(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: test.msu: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.msu a2, a0, a1 +; CHECK-NEXT: mv a0, a2 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.msu(i32 %a, i32 %b, i32 %c) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.mulun(i32, i32, i32) + +define i32 @test.mulun(i32 %a, i32 %b) { +; CHECK-LABEL: test.mulun: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.mulun a0, a0, a1, 5 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.mulun(i32 %a, i32 %b, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.mulhhun(i32, i32, i32) + +define i32 @test.mulhhun(i32 %a, i32 %b) { +; CHECK-LABEL: test.mulhhun: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.mulhhun a0, a0, a1, 5 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.mulhhun(i32 %a, i32 %b, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.mulsn(i32, i32, i32) + +define i32 @test.mulsn(i32 %a, i32 %b) { +; CHECK-LABEL: test.mulsn: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.mulsn a0, a0, a1, 5 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.mulsn(i32 %a, i32 %b, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.mulhhsn(i32, i32, i32) + +define i32 @test.mulhhsn(i32 %a, i32 %b) { +; CHECK-LABEL: test.mulhhsn: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.mulhhsn a0, a0, a1, 5 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.mulhhsn(i32 %a, i32 %b, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.mulurn(i32, i32, i32) + +define i32 @test.mulurn(i32 %a, i32 %b) { +; CHECK-LABEL: test.mulurn: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.mulurn a0, a0, a1, 5 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.mulurn(i32 %a, i32 %b, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.mulhhurn(i32, i32, i32) + +define i32 @test.mulhhurn(i32 %a, i32 %b) { +; CHECK-LABEL: test.mulhhurn: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.mulhhurn a0, a0, a1, 5 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.mulhhurn(i32 %a, i32 %b, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.mulsrn(i32, i32, i32) + +define i32 @test.mulsrn(i32 %a, i32 %b) { +; CHECK-LABEL: test.mulsrn: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.mulsrn a0, a0, a1, 5 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.mulsrn(i32 %a, i32 %b, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.mulhhsrn(i32, i32, i32) + +define i32 @test.mulhhsrn(i32 %a, i32 %b) { +; CHECK-LABEL: test.mulhhsrn: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.mulhhsrn a0, a0, a1, 5 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.mulhhsrn(i32 %a, i32 %b, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.macun(i32, i32, i32, i32) + +define i32 @test.macun(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: test.macun: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.macun a2, a0, a1, 5 +; CHECK-NEXT: mv a0, a2 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.macun(i32 %a, i32 %b, i32 %c, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.machhun(i32, i32, i32, i32) + +define i32 @test.machhun(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: test.machhun: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.machhun a2, a0, a1, 5 +; CHECK-NEXT: mv a0, a2 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.machhun(i32 %a, i32 %b, i32 %c, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.macsn(i32, i32, i32, i32) + +define i32 @test.macsn(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: test.macsn: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.macsn a2, a0, a1, 5 +; CHECK-NEXT: mv a0, a2 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.macsn(i32 %a, i32 %b, i32 %c, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.machhsn(i32, i32, i32, i32) + +define i32 @test.machhsn(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: test.machhsn: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.machhsn a2, a0, a1, 5 +; CHECK-NEXT: mv a0, a2 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.machhsn(i32 %a, i32 %b, i32 %c, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.macurn(i32, i32, i32, i32) + +define i32 @test.macurn(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: test.macurn: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.macurn a2, a0, a1, 5 +; CHECK-NEXT: mv a0, a2 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.macurn(i32 %a, i32 %b, i32 %c, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.machhurn(i32, i32, i32, i32) + +define i32 @test.machhurn(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: test.machhurn: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.machhurn a2, a0, a1, 5 +; CHECK-NEXT: mv a0, a2 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.machhurn(i32 %a, i32 %b, i32 %c, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.macsrn(i32, i32, i32, i32) + +define i32 @test.macsrn(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: test.macsrn: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.macsrn a2, a0, a1, 5 +; CHECK-NEXT: mv a0, a2 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.macsrn(i32 %a, i32 %b, i32 %c, i32 5) + ret i32 %1 +} + +declare i32 @llvm.riscv.cv.mac.machhsrn(i32, i32, i32, i32) + +define i32 @test.machhsrn(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: test.machhsrn: +; CHECK: # %bb.0: +; CHECK-NEXT: cv.machhsrn a2, a0, a1, 5 +; CHECK-NEXT: mv a0, a2 +; CHECK-NEXT: ret + %1 = call i32 @llvm.riscv.cv.mac.machhsrn(i32 %a, i32 %b, i32 %c, i32 5) + ret i32 %1 +} -- GitLab