[llvm] [RISCV] Implement Intrinsics for XCVmac Extension in CV32E40P (PR #83112)

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 27 00:24:32 PST 2024


https://github.com/realqhc updated https://github.com/llvm/llvm-project/pull/83112

>From 0215040c2a9af0b0c05e740944111840f93489b4 Mon Sep 17 00:00:00 2001
From: Qihan Cai <caiqihan021 at hotmail.com>
Date: Tue, 27 Feb 2024 16:15:01 +0800
Subject: [PATCH] [RISCV] Implement Intrinsics for XCVmac Extension in CV32E40P

Implement XCVmac intrinsics and CodeGen 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.
---
 llvm/include/llvm/IR/IntrinsicsRISCVXCV.td |  33 ++++
 llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td |  33 ++++
 llvm/test/CodeGen/RISCV/xcvmac.ll          | 211 +++++++++++++++++++++
 3 files changed, 277 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/xcvmac.ll

diff --git a/llvm/include/llvm/IR/IntrinsicsRISCVXCV.td b/llvm/include/llvm/IR/IntrinsicsRISCVXCV.td
index f1590ad66e362b..af902c7f1ed56f 100644
--- a/llvm/include/llvm/IR/IntrinsicsRISCVXCV.td
+++ b/llvm/include/llvm/IR/IntrinsicsRISCVXCV.td
@@ -18,6 +18,18 @@ class ScalarCoreVBitManipGprIntrinsic
     : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty],
                             [IntrNoMem, IntrSpeculatable]>;
 
+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>>]>;
+
 let TargetPrefix = "riscv" in {
   def int_riscv_cv_bitmanip_extract : ScalarCoreVBitManipGprGprIntrinsic;
   def int_riscv_cv_bitmanip_extractu : ScalarCoreVBitManipGprGprIntrinsic;
@@ -34,4 +46,25 @@ let TargetPrefix = "riscv" in {
     : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
                             [IntrNoMem, IntrWillReturn, IntrSpeculatable,
                             ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
+
+  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/Target/RISCV/RISCVInstrInfoXCV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
index 924e91e15c348f..b62906fcf8e3ca 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
@@ -704,3 +704,36 @@ let Predicates = [HasVendorXCVbitmanip, IsRV32] in {
             (CV_BITREV GPR:$rs1, cv_tuimm2:$radix, cv_tuimm5:$pts)>;
   def : Pat<(bitreverse (XLenVT GPR:$rs)), (CV_BITREV GPR:$rs, 0, 0)>;
 }
+
+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 = [HasVendorXCVmac] in {
+  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">;
+}
diff --git a/llvm/test/CodeGen/RISCV/xcvmac.ll b/llvm/test/CodeGen/RISCV/xcvmac.ll
new file mode 100644
index 00000000000000..68efdf7210f7f5
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/xcvmac.ll
@@ -0,0 +1,211 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -mattr=+m -mattr=+xcvmac -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s
+
+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
+}



More information about the llvm-commits mailing list