[Mlir-commits] [mlir] [MLIR][RISCV] Add VCIX legalization to `VectorToLLVM` pass (PR #74781)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Dec 7 15:26:21 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir

Author: Kolya Panchenko (nikolaypanchenko)

<details>
<summary>Changes</summary>

The changeset continues the work on the VCIX dialect by introducing legalization part to `VectorToLLVM` pass.

---

Patch is 230.68 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74781.diff


23 Files Affected:

- (modified) mlir/include/mlir/Conversion/Passes.td (+4-1) 
- (modified) mlir/include/mlir/Dialect/CMakeLists.txt (+1) 
- (added) mlir/include/mlir/Dialect/VCIX/CMakeLists.txt (+12) 
- (added) mlir/include/mlir/Dialect/VCIX/Transforms.h (+29) 
- (added) mlir/include/mlir/Dialect/VCIX/VCIX.td (+519) 
- (added) mlir/include/mlir/Dialect/VCIX/VCIXAttrs.h (+20) 
- (added) mlir/include/mlir/Dialect/VCIX/VCIXAttrs.td (+91) 
- (added) mlir/include/mlir/Dialect/VCIX/VCIXDialect.h (+28) 
- (modified) mlir/include/mlir/InitAllDialects.h (+2) 
- (modified) mlir/lib/Conversion/VectorToLLVM/CMakeLists.txt (+2) 
- (modified) mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.cpp (+8) 
- (modified) mlir/lib/Dialect/CMakeLists.txt (+1) 
- (added) mlir/lib/Dialect/VCIX/CMakeLists.txt (+2) 
- (added) mlir/lib/Dialect/VCIX/IR/CMakeLists.txt (+16) 
- (added) mlir/lib/Dialect/VCIX/IR/VCIXAttrs.cpp (+12) 
- (added) mlir/lib/Dialect/VCIX/IR/VCIXDialect.cpp (+28) 
- (added) mlir/lib/Dialect/VCIX/IR/VCIXOps.cpp (+174) 
- (added) mlir/lib/Dialect/VCIX/Transforms/CMakeLists.txt (+12) 
- (added) mlir/lib/Dialect/VCIX/Transforms/LegalizeForLLVMExport.cpp (+266) 
- (added) mlir/test/Dialect/VCIX/invalid.mlir (+57) 
- (added) mlir/test/Dialect/VCIX/legalize-for-llvm-rv32.mlir (+1071) 
- (added) mlir/test/Dialect/VCIX/legalize-for-llvm-rv64.mlir (+1071) 
- (added) mlir/test/Dialect/VCIX/ops.mlir (+531) 


``````````diff
diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index 06756ff3df0bb3..c03b0137e6e0f5 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -1294,6 +1294,10 @@ def ConvertVectorToLLVMPass : Pass<"convert-vector-to-llvm"> {
            "bool", /*default=*/"false",
            "Enables the use of ArmSVE dialect while lowering the vector "
        "dialect.">,
+    Option<"vcix", "enable-vcix",
+           "bool", /*default=*/"false",
+           "Enables the use of VCIX dialect while lowering the vector "
+           "dialect to RISC-V target">,
     Option<"x86Vector", "enable-x86vector",
            "bool", /*default=*/"false",
            "Enables the use of X86Vector dialect while lowering the vector "
@@ -1310,5 +1314,4 @@ def ConvertVectorToSPIRV : Pass<"convert-vector-to-spirv"> {
   let constructor = "mlir::createConvertVectorToSPIRVPass()";
   let dependentDialects = ["spirv::SPIRVDialect"];
 }
-
 #endif // MLIR_CONVERSION_PASSES
diff --git a/mlir/include/mlir/Dialect/CMakeLists.txt b/mlir/include/mlir/Dialect/CMakeLists.txt
index 1c4569ecfa5848..1408ced218dbb2 100644
--- a/mlir/include/mlir/Dialect/CMakeLists.txt
+++ b/mlir/include/mlir/Dialect/CMakeLists.txt
@@ -37,5 +37,6 @@ add_subdirectory(Tosa)
 add_subdirectory(Transform)
 add_subdirectory(UB)
 add_subdirectory(Utils)
+add_subdirectory(VCIX)
 add_subdirectory(Vector)
 add_subdirectory(X86Vector)
diff --git a/mlir/include/mlir/Dialect/VCIX/CMakeLists.txt b/mlir/include/mlir/Dialect/VCIX/CMakeLists.txt
new file mode 100644
index 00000000000000..49d4202bf9d8bb
--- /dev/null
+++ b/mlir/include/mlir/Dialect/VCIX/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_mlir_dialect(VCIX vcix)
+add_mlir_doc(VCIXOps VCIXOps Dialects/ -gen-dialect-doc -dialect=vcix)
+
+set(LLVM_TARGET_DEFINITIONS VCIX.td)
+mlir_tablegen(VCIXConversions.inc -gen-llvmir-conversions)
+add_public_tablegen_target(MLIRVCIXConversionsIncGen)
+
+set(LLVM_TARGET_DEFINITIONS VCIXAttrs.td)
+mlir_tablegen(VCIXDialectEnums.h.inc -gen-enum-decls)
+mlir_tablegen(VCIXDialectEnums.cpp.inc -gen-enum-defs)
+add_public_tablegen_target(MLIRVCIXDialectEnumIncGen)
+add_dependencies(mlir-headers MLIRVCIXDialectEnumIncGen)
diff --git a/mlir/include/mlir/Dialect/VCIX/Transforms.h b/mlir/include/mlir/Dialect/VCIX/Transforms.h
new file mode 100644
index 00000000000000..3287e0f535f988
--- /dev/null
+++ b/mlir/include/mlir/Dialect/VCIX/Transforms.h
@@ -0,0 +1,29 @@
+//===- Transforms.h - VCIX Dialect Transformation Entrypoints ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_VCIX_TRANSFORMS_H
+#define MLIR_DIALECT_VCIX_TRANSFORMS_H
+
+namespace mlir {
+
+class LLVMConversionTarget;
+class LLVMTypeConverter;
+class RewritePatternSet;
+
+/// Collect a set of patterns to lower VCIX ops to ops that map to LLVM
+/// intrinsics.
+void populateVCIXLegalizeForLLVMExportPatterns(LLVMTypeConverter &converter,
+                                               RewritePatternSet &patterns);
+
+/// Configure the target to support lowering VCIX ops to ops that map to LLVM
+/// intrinsics.
+void configureVCIXLegalizeForExportTarget(LLVMConversionTarget &target);
+
+} // namespace mlir
+
+#endif // MLIR_DIALECT_VCIX_TRANSFORMS_H
diff --git a/mlir/include/mlir/Dialect/VCIX/VCIX.td b/mlir/include/mlir/Dialect/VCIX/VCIX.td
new file mode 100644
index 00000000000000..655a563764632a
--- /dev/null
+++ b/mlir/include/mlir/Dialect/VCIX/VCIX.td
@@ -0,0 +1,519 @@
+//===-- VCIX.td - VCIX dialect operation definitions *- tablegen -*--------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// The file defines the basic operations for the VCIX dialect.
+//
+// The SiFive Vector Coprocessor Interface (VCIX) provides a flexible mechanism
+// to extend application processors with custom coprocessors and
+// variable-latency arithmetic units. The interface offers throughput comparable
+// to that of standard RISC-V vector instructions. To accelerate performance,
+// system designers may use VCIX as a low-latency, high-throughput interface to
+// a coprocessor
+//
+// https://www.sifive.com/document-file/sifive-vector-coprocessor-interface-vcix-software
+//
+//===----------------------------------------------------------------------===//
+#ifndef VCIX
+#define VCIX
+
+include "mlir/IR/EnumAttr.td"
+include "mlir/IR/OpBase.td"
+include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
+include "mlir/Interfaces/SideEffectInterfaces.td"
+
+include "mlir/Dialect/VCIX/VCIXAttrs.td"
+
+//===----------------------------------------------------------------------===//
+// VCIX dialect definition.
+//===----------------------------------------------------------------------===//
+
+def VCIX_Dialect : Dialect {
+  let name = "vcix";
+  let cppNamespace = "::mlir::vcix";
+  let description = [{
+     The SiFive Vector Coprocessor Interface (VCIX) provides a flexible mechanism
+     to extend application processors with custom coprocessors and
+     variable-latency arithmetic units. The interface offers throughput comparable
+     to that of standard RISC-V vector instructions. To accelerate performance,
+     system designers may use VCIX as a low-latency, high-throughput interface to
+     a coprocessor
+
+     https://www.sifive.com/document-file/sifive-vector-coprocessor-interface-vcix-software
+  }];
+
+  let usePropertiesForAttributes = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// VCIX Ops
+//===----------------------------------------------------------------------===//
+class VCIX_Op<string mnemonic, list<Trait> traits = []>
+    : Op<VCIX_Dialect, mnemonic, traits> {}
+
+class VCIX_IntrinOp<string mnemonic, list<Trait> traits = []>
+    : LLVM_OpBase<VCIX_Dialect, "intrin." #mnemonic, traits> {}
+
+//===----------------------------------------------------------------------===//
+// Unary VCIX operations
+//===----------------------------------------------------------------------===//
+def VCIX_UnaryROOp : VCIX_Op<"unary.ro", []> {
+  let summary = "Unary VCIX operation with side effects and without result";
+  let description = [{
+    Unary VCIX operation that has some side effects and does not produce result
+
+    Correponds to
+    ```
+    Mnemonic    funct6 vm  rs2   rs1  funct3  rd     Destination   Sources
+    sf.vc.x     0000-- 1  -----  xs1   100   -----   none          scalar xs1
+    sf.vc.i     0000-- 1  ----- simm   011   -----   none          simm[4:0]
+    ```
+  }];
+
+  let arguments = (ins AnyTypeOf<[I<64>, I<32>, I<5>]>: $op,
+                       RVLType: $rvl,
+                       OpcodeIntAttr: $opcode,
+                       VCIX_SewLmulAttr: $sew_lmul,
+                       RAttr: $rs2,
+                       RAttr: $rd);
+
+  let assemblyFormat = [{
+    $sew_lmul $op `,` $rvl  attr-dict `:` `(` type($op) `,` type($rvl) `)`
+  }];
+
+  let hasVerifier = 1;
+}
+
+def VCIX_UnaryOp : VCIX_Op<"unary", []> {
+  let summary = "unary VCIX operation";
+  let description = [{
+    Unary VCIX operation that produces result
+
+    Correponds to
+    ```
+    Mnemonic    funct6 vm  rs2   rs1  funct3  rd     Destination   Sources
+    sf.vc.v.x   0000-- 0  -----  xs1   100    vd     vector vd     scalar xs1
+    sf.vc.v.i   0000-- 0  ----- simm   011    vd     vector vd     simm[4:0]
+    ```
+  }];
+
+  let arguments = (ins AnyTypeOf<[I<64>, I<32>, I<5>]>: $op,
+                       Optional<RVLType>: $rvl,
+                       OpcodeIntAttr: $opcode,
+                       RAttr: $rs2);
+
+  let results = (outs VectorOfRank1: $result);
+
+  let assemblyFormat = [{
+    $op (`,` $rvl^)?  attr-dict
+      `:` `(` type($op) (`,` type($rvl)^)? `)` `->` type($result)
+  }];
+
+  let hasVerifier = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// Binary VCIX operations
+//===----------------------------------------------------------------------===//
+def VCIX_BinaryROOp : VCIX_Op<"binary.ro", []> {
+  let summary = "Read-only binary VCIX operation";
+  let description = [{
+    Read-only binary VCIX operation that does not produce result
+
+    Correponds to
+    ```
+    Mnemonic    funct6 vm  rs2   rs1  funct3  rd     Destination   Sources
+    sf.vc.v.vv  0010-- 1   vs2   vs1   000    -----     none       vector vs1, vector vs2
+    sf.vc.v.xv  0010-- 1   vs2   xs1   100    -----     none       scalar xs1, vector vs2
+    sf.vc.v.iv  0010-- 1   vs2  simm   011    -----     none       simm[4:0],  vector vs2
+    sf.vc.v.fv  0010-- 1   vs2   fs1   101    -----     none       scalar fs1, vector vs2
+    ```
+  }];
+
+  let arguments = (ins VectorOfRank1OrScalar: $op1,
+                       VectorOfRank1: $op2,
+                       Optional<RVLType>: $rvl,
+                       OpcodeIntAttr: $opcode,
+                       RAttr: $rd);
+
+  let assemblyFormat = [{
+    $op1 `,` $op2 (`,` $rvl^)? attr-dict `:`
+      `(` type($op1) `,` type($op2) (`,` type($rvl)^)? `)`
+  }];
+
+  let hasVerifier = 1;
+}
+
+def VCIX_BinaryOp : VCIX_Op<"binary", []> {
+  let summary = "binary VCIX operation";
+  let description = [{
+    Binary VCIX operation that produces result
+
+    Correponds to
+    ```
+    Mnemonic    funct6 vm  rs2   rs1  funct3  rd     Destination   Sources
+    sf.vc.v.vv  0010-- 0   vs2   vs1   000    vd     vector vd     vector vs1, vector vs2
+    sf.vc.v.xv  0010-- 0   vs2   xs1   100    vd     vector vd     scalar xs1, vector vs2
+    sf.vc.v.iv  0010-- 0   vs2  simm   011    vd     vector vd     simm[4:0],  vector vs2
+    sf.vc.v.fv  0010-- 0   vs2   fs1   101    vd     vector vd     scalar fs1, vector vs2
+    ```
+  }];
+
+  let arguments = (ins VectorOfRank1OrScalar: $op1,
+                       VectorOfRank1: $op2,
+                       Optional<RVLType>: $rvl,
+                       OpcodeIntAttr: $opcode);
+
+  let results = (outs VectorOfRank1: $result);
+
+  let assemblyFormat = [{
+    $op1 `,` $op2 (`,` $rvl^)? attr-dict `:`
+      `(` type($op1) `,` type($op2) (`,` type($rvl)^)? `)` `->` type($result)
+  }];
+
+  let hasVerifier = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// Ternary VCIX operations
+//===----------------------------------------------------------------------===//
+def VCIX_TernaryROOp : VCIX_Op<"ternary.ro", []> {
+  let summary = "Ternary VCIX operation";
+  let description = [{
+    Ternary VCIX operation that does not generate result
+
+    Correponds to
+    ```
+    Mnemonic    funct6 vm  rs2   rs1  funct3  rd     Destination   Sources
+    sf.vc.vvv   1010-- 1   vs2   vs1  000     vd        none       vector vs1, vector vs2, vector vd
+    sf.vc.xvv   1010-- 1   vs2   xs1  100     vd        none       scalar xs1, vector vs2, vector vd
+    sf.vc.ivv   1010-- 1   vs2   simm 011     vd        none       simm[4:0], vector vs2, vector vd
+    sf.vc.fvv   10101- 1   vs2   fs1  101     vd        none       scalar fs1, vector vs2, vector vd
+    ```
+  }];
+
+  let arguments = (ins VectorOfRank1OrScalar: $op1,
+                       VectorOfRank1: $op2,
+                       VectorOfRank1: $op3,
+                       Optional<RVLType>: $rvl,
+                       OpcodeIntAttr: $opcode);
+
+  let assemblyFormat = [{
+    $op1 `,` $op2 `,` $op3 (`,` $rvl^)? attr-dict `:`
+      `(` type($op1) `,` type($op2) `,` type($op3) (`,` type($rvl)^)? `)`
+  }];
+
+  let hasVerifier = 1;
+}
+
+def VCIX_TernaryOp : VCIX_Op<"ternary", []> {
+  let summary = "Ternary VCIX operation";
+  let description = [{
+    Ternary VCIX operation that produces result
+
+    Correponds to
+    ```
+    Mnemonic    funct6 vm  rs2   rs1  funct3  rd     Destination   Sources
+    sf.vc.v.vvv 1010-- 0   vs2   vs1  000     vd     vector vd     vector vs1, vector vs2, vector vd
+    sf.vc.v.xvv 1010-- 0   vs2   xs1  100     vd     vector vd     scalar xs1, vector vs2, vector vd
+    sf.vc.v.ivv 1010-- 0   vs2   simm 011     vd     vector vd     simm[4:0], vector vs2, vector vd
+    sf.vc.v.fvv 10101- 0   vs2   fs1  101     vd     vector vd     scalar fs1, vector vs2, vector vd
+    ```
+  }];
+
+  let arguments = (ins VectorOfRank1OrScalar: $op1,
+                       VectorOfRank1: $op2,
+                       VectorOfRank1: $op3,
+                       Optional<RVLType>: $rvl,
+                       OpcodeIntAttr: $opcode);
+
+  let results = (outs VectorOfRank1: $result);
+
+  let assemblyFormat = [{
+    $op1 `,` $op2 `,` $op3 (`,` $rvl^)? attr-dict `:`
+      `(` type($op1) `,` type($op2) `,` type($op3) (`,` type($rvl)^)? `)` `->` type($result)
+  }];
+
+  let hasVerifier = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// Wide ternary VCIX operations
+//===----------------------------------------------------------------------===//
+def VCIX_WideTernaryROOp : VCIX_Op<"wide.ternary.ro", []> {
+  let summary = "Ternary VCIX operation";
+  let description = [{
+    Wide Ternary VCIX operation that does not produce result
+
+    Correponds to
+    ```
+    Mnemonic    funct6 vm  rs2   rs1  funct3  rd     Destination   Sources
+    sf.vc.vvw   1111-- 1   vs2   vs1  000     vd      none         vector vs1, vector vs2, wide vd
+    sf.vc.xvw   1111-- 1   vs2   xs1  100     vd      none         scalar xs1, vector vs2, wide vd
+    sf.vc.ivw   1111-- 1   vs2   simm 011     vd      none         simm[4:0], vector vs2, wide vd
+    sf.vc.fvw   11111- 1   vs2   fs1  101     vd      none         scalar fs1, vector vs2, wide vd
+    ```
+  }];
+
+  let arguments = (ins VectorOfRank1OrScalar: $op1,
+                       VectorOfRank1: $op2,
+                       VectorOfRank1: $op3,
+                       Optional<RVLType>: $rvl,
+                       OpcodeIntAttr: $opcode);
+
+  let assemblyFormat = [{
+    $op1 `,` $op2 `,` $op3 (`,` $rvl^)? attr-dict `:`
+      `(` type($op1) `,` type($op2) `,` type($op3) (`,` type($rvl)^)? `)`
+  }];
+
+  let hasVerifier = 1;
+}
+
+def VCIX_WideTernaryOp : VCIX_Op<"wide.ternary", []> {
+  let summary = "Ternary VCIX operation";
+  let description = [{
+    Wide Ternary VCIX operation that produces result
+
+    Correponds to
+    ```
+    Mnemonic    funct6 vm  rs2   rs1  funct3  rd     Destination   Sources
+    sf.vc.v.vvw 1111-- 0   vs2   vs1  000     vd     wide vd       vector vs1, vector vs2, wide vd
+    sf.vc.v.xvw 1111-- 0   vs2   xs1  100     vd     wide vd       scalar xs1, vector vs2, wide vd
+    sf.vc.v.ivw 1111-- 0   vs2   simm 011     vd     wide vd       simm[4:0], vector vs2, wide vd
+    sf.vc.v.fvw 11111- 0   vs2   fs1  101     vd     wide vd       scalar fs1, vector vs2, wide vd
+    ```
+  }];
+
+  let arguments = (ins VectorOfRank1OrScalar: $op1,
+                       VectorOfRank1: $op2,
+                       VectorOfRank1: $op3,
+                       Optional<RVLType>: $rvl,
+                       OpcodeIntAttr: $opcode);
+
+  let results = (outs VectorOfRank1: $result);
+
+  let assemblyFormat = [{
+    $op1 `,` $op2 `,` $op3 (`,` $rvl^)? attr-dict `:`
+      `(` type($op1) `,` type($op2) `,` type($op3) (`,` type($rvl)^)? `)` `->` type($result)
+  }];
+
+  let hasVerifier = 1;
+}
+
+def VCIX_UnaryIntrinROOp : VCIX_IntrinOp<"unary.ro"> {
+  let arguments = (ins AnyTypeOf<[I<64>, I<32>, I<5>]>: $op,
+                       RVLIntrinType: $rvl,
+                       OpcodeIntrinIntAttr: $opcode,
+                       VCIX_SewLmulAttr: $sew_lmul,
+                       RIntrinAttr: $rs2,
+                       RIntrinAttr: $rd);
+
+  string llvmBuilder = [{
+      const unsigned xlenWidth = getXlenFromOpcode($opcode);
+      llvm::Type *xlen =
+          llvm::Type::getIntNTy(moduleTranslation.getLLVMContext(), xlenWidth);
+      llvm::Value *opcodeConst = getLLVMConstant(
+          xlen, $opcode, $_location, moduleTranslation);
+
+      llvm::Value *rs2Const = getLLVMConstant(
+          xlen, $rs2, $_location, moduleTranslation);
+
+      llvm::Value *rdConst = getLLVMConstant(
+          xlen, $rd, $_location, moduleTranslation);
+
+      auto intId = getUnaryROIntrinsicId($sew_lmul, op.getOp().getType());
+      createIntrinsicCall(builder, intId,
+                          {opcodeConst, rs2Const, rdConst, $op, $rvl},
+                          {xlen, xlen, xlen});
+  }];
+}
+
+def VCIX_UnaryIntrinOp : VCIX_IntrinOp<"unary"> {
+  let arguments = (ins AnyTypeOf<[I<64>, I<32>, I<5>]>: $op,
+                       Optional<RVLIntrinType>: $rvl,
+                       OpcodeIntrinIntAttr: $opcode,
+                       RIntrinAttr: $rs2);
+
+  let results = (outs VectorOfRank1: $result);
+
+  string llvmBuilder = [{
+      const unsigned xlenWidth = getXlenFromOpcode($opcode);
+      llvm::Type *xlen =
+          llvm::Type::getIntNTy(moduleTranslation.getLLVMContext(), xlenWidth);
+      llvm::Value *opcodeConst = getLLVMConstant(
+          xlen, $opcode, $_location, moduleTranslation);
+
+      llvm::Value *rs2Const = getLLVMConstant(
+          xlen, $rs2, $_location, moduleTranslation);
+
+      VectorType vt = op.getResult().getType().cast<VectorType>();
+      auto intId = getUnaryIntrinsicId(op.getOp().getType(), vt);
+      llvm::Value *rvl =
+          convertRvl(builder, $rvl, vt, xlen, $_location, moduleTranslation);
+
+      $result = createIntrinsicCall(
+          builder, intId, {opcodeConst, rs2Const, $op, rvl},
+          {$_resultType, xlen, xlen, xlen});
+  }];
+}
+
+def VCIX_BinaryIntrinROOp : VCIX_IntrinOp<"binary.ro"> {
+  let arguments = (ins VectorOfRank1OrScalarIntrin: $op1,
+                       VectorOfRank1: $op2,
+                       Optional<RVLIntrinType>: $rvl,
+                       OpcodeIntrinIntAttr: $opcode,
+                       RIntrinAttr: $rd);
+
+  string llvmBuilder = [{
+      const unsigned xlenWidth = getXlenFromOpcode($opcode);
+      llvm::Type *xlen =
+          llvm::Type::getIntNTy(moduleTranslation.getLLVMContext(), xlenWidth);
+      llvm::Value *opcodeConst = getLLVMConstant(
+          xlen, $opcode, $_location, moduleTranslation);
+
+      llvm::Value *rdConst = getLLVMConstant(
+          xlen, $rd, $_location, moduleTranslation);
+
+      auto intId = getBinaryROIntrinsicId(op.getOp1().getType());
+      VectorType vt = op.getOp2().getType().cast<VectorType>();
+      llvm::Value *rvl =
+          convertRvl(builder, $rvl, vt, xlen, $_location, moduleTranslation);
+
+      createIntrinsicCall(builder, intId,
+                          {opcodeConst, rdConst, $op2, $op1, rvl},
+                          {xlen, $op2->getType(), $op1->getType(), xlen});
+  }];
+}
+
+def VCIX_BinaryIntrinOp : VCIX_IntrinOp<"binary"> {
+  let arguments = (ins VectorOfRank1OrScalarIntrin: $op1,
+                       VectorOfRank1: $op2,
+                       Optional<RVLIntrinType>: $rvl,
+                       OpcodeIntrinIntAttr: $opcode);
+
+  let results = (outs VectorOfRank1: $result);
+
+  string llvmBuilder = [{
+      const unsigned xlenWidth = getXlenFromOpcode($opcode);
+      llvm::Type *xlen = llvm::Type::getIntNTy(
+          moduleTranslation.getLLVMContext(), xlenWidth);
+      llvm::Value *opcodeConst = getLLVMConstant(
+          xlen, $opcode, $_location, moduleTranslation);
+
+      auto intId = getBinaryIntrinsicId(op.getOp1().getType());
+      VectorType vt = op.getResult().getType().cast<VectorType>();
+      llvm::Value *rvl =
+          convertRvl(builder, $rvl, vt, xlen, $_location, moduleTranslation);
+
+      $result = createIntrinsicCall(
+          builder, intId, {opcodeConst, $op2, $op1, rvl},
+          {$_resultType, xlen, $op2->getType(), $op1->getType(), xlen});
+  }];
+}
+
+def VCIX_TernaryIntrinROOp : VCIX_IntrinOp<"ternary.ro"> {
+  let arguments = (ins VectorOfRank1OrScalarIntrin: $op1,
+                       VectorOfRank1: $op2,
+                       VectorOfRank1: $op3,
+                       Optional<RVLIntrinType>: $rvl,
+       ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/74781


More information about the Mlir-commits mailing list