diff --git a/llvm/include/llvm/IR/IntrinsicsRISCVXCV.td b/llvm/include/llvm/IR/IntrinsicsRISCVXCV.td index 8b4f4966fbd9aa..38263f375c4692 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCVXCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCVXCV.td @@ -30,6 +30,18 @@ class ScalarCoreVAluGprGprGprIntrinsic : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, 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>]>; + +class ScalarCoreVMacGprGprGprImmIntrinsic + : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrWillReturn, IntrSpeculatable, ImmArg>]>; + let TargetPrefix = "riscv" in { def int_riscv_cv_bitmanip_extract : ScalarCoreVBitManipGprGprIntrinsic; def int_riscv_cv_bitmanip_extractu : ScalarCoreVBitManipGprGprIntrinsic; @@ -57,4 +69,25 @@ let TargetPrefix = "riscv" in { def int_riscv_cv_alu_subun : ScalarCoreVAluGprGprGprIntrinsic; def int_riscv_cv_alu_subrn : ScalarCoreVAluGprGprGprIntrinsic; def int_riscv_cv_alu_suburn : ScalarCoreVAluGprGprGprIntrinsic; + + 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 79b960c6da21c4..3bd6da28682863 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td @@ -826,3 +826,36 @@ let Predicates = [HasVendorXCVbi, IsRV32], AddedComplexity = 2 in { def : Selectbi; def : Selectbi; } + +class PatCoreVMacGprGprGpr + : Pat<(!cast("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd), + (!cast("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2)>; +class PatCoreVMacGprGprGprUimm5 + : Pat<(!cast("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd, cv_tuimm5:$imm5), + (!cast("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5)>; +class PatCoreVMacGprGprUimm5 + : Pat<(!cast("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5), + (!cast("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 +}