-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MLIR][VCIX] Support VCIX intrinsics in LLVMIR dialect #75875
Conversation
@llvm/pr-subscribers-mlir-core @llvm/pr-subscribers-mlir Author: Kolya Panchenko (nikolaypanchenko) ChangesThe changeset extends LLVMIR intrinsics with VCIX intrinsics. Source: https://www.sifive.com/document-file/sifive-vector-coprocessor-interface-vcix-software Patch is 26.93 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/75875.diff 13 Files Affected:
diff --git a/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt b/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
index 8e41fcc05a161e..4c8078c545c735 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
+++ b/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
@@ -71,3 +71,11 @@ mlir_tablegen(ROCDLConversions.inc -gen-llvmir-conversions)
mlir_tablegen(ROCDLOpsAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=rocdl)
mlir_tablegen(ROCDLOpsAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=rocdl)
add_public_tablegen_target(MLIRROCDLConversionsIncGen)
+
+add_mlir_dialect(VCIXOps vcix)
+add_mlir_doc(VCIXOps RVCIXDialect Dialects/ -gen-dialect-doc -dialect=rocdl)
+set(LLVM_TARGET_DEFINITIONS VCIXOps.td)
+mlir_tablegen(VCIXConversions.inc -gen-llvmir-conversions)
+mlir_tablegen(VCIXOpsAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=rocdl)
+mlir_tablegen(VCIXOpsAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=rocdl)
+add_public_tablegen_target(MLIRVCIXConversionsIncGen)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/VCIXDialect.h b/mlir/include/mlir/Dialect/LLVMIR/VCIXDialect.h
new file mode 100644
index 00000000000000..3c911d6bc8677b
--- /dev/null
+++ b/mlir/include/mlir/Dialect/LLVMIR/VCIXDialect.h
@@ -0,0 +1,40 @@
+//===- VCIXDialect.h - MLIR VCIX IR dialect -------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// 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 MLIR_DIALECT_LLVMIR_VCIXDIALECT_H_
+#define MLIR_DIALECT_LLVMIR_VCIXDIALECT_H_
+
+#include "mlir/Bytecode/BytecodeOpInterface.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/Dialect.h"
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/Interfaces/SideEffectInterfaces.h"
+
+///// Ops /////
+#define GET_ATTRDEF_CLASSES
+#include "mlir/Dialect/LLVMIR/VCIXOpsAttributes.h.inc"
+
+#define GET_OP_CLASSES
+#include "mlir/Dialect/LLVMIR/VCIXOps.h.inc"
+
+#include "mlir/Dialect/LLVMIR/VCIXOpsDialect.h.inc"
+
+#endif /* MLIR_DIALECT_LLVMIR_VCIXDIALECT_H_ */
diff --git a/mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td b/mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td
new file mode 100644
index 00000000000000..3f1fa37988c199
--- /dev/null
+++ b/mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td
@@ -0,0 +1,112 @@
+//===-- 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 VCIXIR_OPS
+
+include "mlir/IR/OpBase.td"
+include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
+
+//===----------------------------------------------------------------------===//
+// VCIX dialect definition.
+//===----------------------------------------------------------------------===//
+
+def VCIX_Dialect : Dialect {
+ let name = "vcix";
+ let cppNamespace = "::mlir::vcix";
+ let dependentDialects = ["LLVM::LLVMDialect"];
+ 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
+ }];
+}
+
+// Special version for intrinsic version where int attr is zext to i32 or i64
+// depending on xlen of the target
+def VCIX_VectorOrScalar
+ : AnyTypeOf<[LLVM_AnyVector, I<64>, I<32>, F<16>, F<32>, F<64>]>;
+def VCIX_OpcodeAttr : AnyAttrOf<[I32Attr, I64Attr]>;
+def VCIX_Register : AnyTypeOf<[I32, I64]>;
+def VCIX_ImmAttr : AnyAttrOf<[I32Attr, I64Attr]>;
+def VCIX_VL : AnyTypeOf<[I<64>, I<32>]>;
+
+class VCIX_Op<string mnemonic, list<Trait> traits = []>
+ : LLVM_OpBase<VCIX_Dialect, mnemonic, traits> {
+}
+
+def VCIX_BinaryImmOp
+ : VCIX_Op<"v.iv">,
+ Results<(outs LLVM_AnyVector: $res)>,
+ Arguments<(ins VCIX_OpcodeAttr: $opcode,
+ LLVM_AnyVector: $vs2,
+ VCIX_ImmAttr: $imm,
+ VCIX_Register: $rd,
+ Optional<VCIX_VL>: $vl)> {
+ string llvmBuilder = [{
+ llvm::Type *xlen =getXlenType($opcode, moduleTranslation);
+ llvm::Value *opcodeConst = mlir::LLVM::detail::getLLVMConstant(
+ xlen, $opcode, $_location, moduleTranslation);
+ llvm::Value *immConst = mlir::LLVM::detail::getLLVMConstant(
+ xlen, $imm, $_location, moduleTranslation);
+ VectorType vt = op.getResult().getType().cast<VectorType>();
+ llvm::Value *vl =
+ createVL(builder, $vl, vt, xlen, $_location, moduleTranslation);
+ $res = createIntrinsicCall(
+ builder, llvm::Intrinsic::riscv_sf_vc_v_iv_se,
+ {opcodeConst, $vs2, immConst, vl},
+ {$_resultType, xlen, $vs2->getType(), xlen, xlen});
+ }];
+}
+
+def VCIX_BinaryOp
+ : VCIX_Op<"v.sv">,
+ Results<(outs LLVM_AnyVector: $res)>,
+ Arguments<(ins VCIX_OpcodeAttr: $opcode,
+ LLVM_AnyVector: $vs2,
+ VCIX_VectorOrScalar: $op,
+ Optional<VCIX_VL>: $vl)> {
+ string llvmBuilder = [{
+ llvm::Type *xlen = getXlenType($opcode, moduleTranslation);
+ llvm::Value *opcodeConst = mlir::LLVM::detail::getLLVMConstant(
+ xlen, $opcode, $_location, moduleTranslation);
+ llvm::Intrinsic::ID id;
+ llvm::Type *opType = $op->getType();
+ if (opType->isVectorTy()) {
+ id = llvm::Intrinsic::riscv_sf_vc_v_vv_se;
+ } else if (opType->isIntegerTy()) {
+ id = llvm::Intrinsic::riscv_sf_vc_v_xv_se;
+ } else {
+ id = llvm::Intrinsic::riscv_sf_vc_v_fv_se;
+ }
+ VectorType vt = op.getResult().getType().cast<VectorType>();
+ llvm::Value *vl =
+ createVL(builder, $vl, vt, xlen, $_location, moduleTranslation);
+ $res = createIntrinsicCall(
+ builder, id, {opcodeConst, $vs2, $op, vl},
+ {$_resultType, xlen, $vs2->getType(), $op->getType(), xlen});
+ }];
+}
+
+#endif // VCIXIR_OPS
diff --git a/mlir/include/mlir/Target/LLVMIR/Dialect/All.h b/mlir/include/mlir/Target/LLVMIR/Dialect/All.h
index 0b37e23e45118b..de9d5872cc4546 100644
--- a/mlir/include/mlir/Target/LLVMIR/Dialect/All.h
+++ b/mlir/include/mlir/Target/LLVMIR/Dialect/All.h
@@ -28,6 +28,7 @@
#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/SPIRV/SPIRVToLLVMIRTranslation.h"
+#include "mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/X86Vector/X86VectorToLLVMIRTranslation.h"
namespace mlir {
@@ -48,6 +49,7 @@ static inline void registerAllToLLVMIRTranslations(DialectRegistry ®istry) {
registerOpenMPDialectTranslation(registry);
registerROCDLDialectTranslation(registry);
registerSPIRVDialectTranslation(registry);
+ registerVCIXDialectTranslation(registry);
registerX86VectorDialectTranslation(registry);
// Extension required for translating GPU offloading Ops.
diff --git a/mlir/include/mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h b/mlir/include/mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h
new file mode 100644
index 00000000000000..d84d03a2257928
--- /dev/null
+++ b/mlir/include/mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h
@@ -0,0 +1,31 @@
+//===- VCIXToLLVMIRTranslation.h - VCIX to LLVM IR ------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides registration calls for VCIX dialect to LLVM IR translation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_TARGET_LLVMIR_DIALECT_VCIX_VCIXTOLLVMIRTRANSLATION_H
+#define MLIR_TARGET_LLVMIR_DIALECT_VCIX_VCIXTOLLVMIRTRANSLATION_H
+
+namespace mlir {
+
+class DialectRegistry;
+class MLIRContext;
+
+/// Register the VCIX dialect and the translation from it to the LLVM IR in the
+/// given registry;
+void registerVCIXDialectTranslation(DialectRegistry ®istry);
+
+/// Register the VCIX dialect and the translation from it in the registry
+/// associated with the given context.
+void registerVCIXDialectTranslation(MLIRContext &context);
+
+} // namespace mlir
+
+#endif // MLIR_TARGET_LLVMIR_DIALECT_VCIX_VCIXTOLLVMIRTRANSLATION_H
diff --git a/mlir/lib/Dialect/LLVMIR/CMakeLists.txt b/mlir/lib/Dialect/LLVMIR/CMakeLists.txt
index b00259677697a5..392065b859ee54 100644
--- a/mlir/lib/Dialect/LLVMIR/CMakeLists.txt
+++ b/mlir/lib/Dialect/LLVMIR/CMakeLists.txt
@@ -85,3 +85,25 @@ add_mlir_dialect_library(MLIRROCDLDialect
MLIRLLVMDialect
MLIRSideEffectInterfaces
)
+
+add_mlir_dialect_library(MLIRVCIXDialect
+ IR/VCIXDialect.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/LLVMIR
+
+ DEPENDS
+ MLIRGPUCompilationAttrInterfacesIncGen
+ MLIRVCIXOpsIncGen
+ MLIRVCIXConversionsIncGen
+ intrinsics_gen
+
+ LINK_COMPONENTS
+ AsmParser
+ Core
+
+ LINK_LIBS PUBLIC
+ MLIRIR
+ MLIRLLVMDialect
+ MLIRSideEffectInterfaces
+ )
diff --git a/mlir/lib/Dialect/LLVMIR/IR/VCIXDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/VCIXDialect.cpp
new file mode 100644
index 00000000000000..30ad5bfed1c0b2
--- /dev/null
+++ b/mlir/lib/Dialect/LLVMIR/IR/VCIXDialect.cpp
@@ -0,0 +1,55 @@
+//===- VCIXDialect.cpp - MLIR VCIX ops implementation ---------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the VCIX dialect and its operations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/LLVMIR/VCIXDialect.h"
+
+#include "mlir/Dialect/GPU/IR/CompilationInterfaces.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/DialectImplementation.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/Operation.h"
+#include "llvm/ADT/TypeSwitch.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/SourceMgr.h"
+
+using namespace mlir;
+using namespace vcix;
+
+#include "mlir/Dialect/LLVMIR/VCIXOpsDialect.cpp.inc"
+
+//===----------------------------------------------------------------------===//
+// VCIXDialect initialization, type parsing, and registration.
+//===----------------------------------------------------------------------===//
+
+// TODO: This should be the llvm.rocdl dialect once this is supported.
+void VCIXDialect::initialize() {
+ addOperations<
+#define GET_OP_LIST
+#include "mlir/Dialect/LLVMIR/VCIXOps.cpp.inc"
+ >();
+
+ addAttributes<
+#define GET_ATTRDEF_LIST
+#include "mlir/Dialect/LLVMIR/VCIXOpsAttributes.cpp.inc"
+ >();
+}
+
+#define GET_OP_CLASSES
+#include "mlir/Dialect/LLVMIR/VCIXOps.cpp.inc"
+
+#define GET_ATTRDEF_CLASSES
+#include "mlir/Dialect/LLVMIR/VCIXOpsAttributes.cpp.inc"
diff --git a/mlir/lib/Target/LLVMIR/CMakeLists.txt b/mlir/lib/Target/LLVMIR/CMakeLists.txt
index 94280a2ec9012b..08e10fc3d965bb 100644
--- a/mlir/lib/Target/LLVMIR/CMakeLists.txt
+++ b/mlir/lib/Target/LLVMIR/CMakeLists.txt
@@ -58,6 +58,7 @@ add_mlir_translation_library(MLIRToLLVMIRTranslationRegistration
MLIROpenACCToLLVMIRTranslation
MLIROpenMPToLLVMIRTranslation
MLIRROCDLToLLVMIRTranslation
+ MLIRVCIXToLLVMIRTranslation
MLIRSPIRVToLLVMIRTranslation
)
diff --git a/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt b/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt
index c9d916d8a5d82d..87bed032d2e2da 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt
+++ b/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt
@@ -9,5 +9,6 @@ add_subdirectory(NVVM)
add_subdirectory(OpenACC)
add_subdirectory(OpenMP)
add_subdirectory(ROCDL)
+add_subdirectory(VCIX)
add_subdirectory(SPIRV)
add_subdirectory(X86Vector)
diff --git a/mlir/lib/Target/LLVMIR/Dialect/VCIX/CMakeLists.txt b/mlir/lib/Target/LLVMIR/Dialect/VCIX/CMakeLists.txt
new file mode 100644
index 00000000000000..d2622af16d9383
--- /dev/null
+++ b/mlir/lib/Target/LLVMIR/Dialect/VCIX/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_mlir_translation_library(MLIRVCIXToLLVMIRTranslation
+ VCIXToLLVMIRTranslation.cpp
+
+ DEPENDS
+ MLIRVCIXConversionsIncGen
+
+ LINK_COMPONENTS
+ Core
+
+ LINK_LIBS PUBLIC
+ MLIRIR
+ MLIRLLVMDialect
+ MLIRVCIXDialect
+ MLIRSupport
+ MLIRTargetLLVMIRExport
+ )
diff --git a/mlir/lib/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.cpp
new file mode 100644
index 00000000000000..40aec7eb406782
--- /dev/null
+++ b/mlir/lib/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.cpp
@@ -0,0 +1,89 @@
+//===- VCIXToLLVMIRTranslation.cpp - Translate VCIX to LLVM IR ----------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a translation between the MLIR VCIX dialect and
+// LLVM IR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h"
+#include "mlir/Dialect/LLVMIR/VCIXDialect.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/Operation.h"
+#include "mlir/Target/LLVMIR/ModuleTranslation.h"
+
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicsRISCV.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace mlir;
+using namespace mlir::LLVM;
+using mlir::LLVM::detail::createIntrinsicCall;
+
+/// Infer XLen type from opcode's type. This is done to avoid passing target
+/// option around
+static llvm::Type *getXlenType(Attribute opcodeAttr,
+ LLVM::ModuleTranslation &moduleTranslation) {
+ auto intAttr = opcodeAttr.cast<IntegerAttr>();
+ unsigned xlenWidth = intAttr.getType().cast<IntegerType>().getWidth();
+ return llvm::Type::getIntNTy(moduleTranslation.getLLVMContext(), xlenWidth);
+}
+
+/// Return VL for VCIX intrinsic. If vl was previously set, return it,
+/// otherwise construct a constant using fixed vector type
+static llvm::Value *createVL(llvm::IRBuilderBase &builder, llvm::Value *vl,
+ VectorType vtype, llvm::Type *xlen, Location loc,
+ LLVM::ModuleTranslation &moduleTranslation) {
+ if (vl) {
+ assert(vtype.isScalable() &&
+ "vl parameter must be set for scalable vectors");
+ return builder.CreateZExtOrTrunc(vl, xlen);
+ }
+
+ assert(vtype.getRank() == 1 && "Only 1-d fixed vectors are supported");
+ return mlir::LLVM::detail::getLLVMConstant(
+ xlen,
+ IntegerAttr::get(IntegerType::get(&moduleTranslation.getContext(), 64),
+ vtype.getShape()[0]),
+ loc, moduleTranslation);
+}
+
+namespace {
+/// Implementation of the dialect interface that converts operations belonging
+/// to the VCIX dialect to LLVM IR.
+class VCIXDialectLLVMIRTranslationInterface
+ : public LLVMTranslationDialectInterface {
+public:
+ using LLVMTranslationDialectInterface::LLVMTranslationDialectInterface;
+
+ /// Translates the given operation to LLVM IR using the provided IR builder
+ /// and saving the state in `moduleTranslation`.
+ LogicalResult
+ convertOperation(Operation *op, llvm::IRBuilderBase &builder,
+ LLVM::ModuleTranslation &moduleTranslation) const final {
+ Operation &opInst = *op;
+#include "mlir/Dialect/LLVMIR/VCIXConversions.inc"
+
+ return failure();
+ }
+};
+} // namespace
+
+void mlir::registerVCIXDialectTranslation(DialectRegistry ®istry) {
+ registry.insert<vcix::VCIXDialect>();
+ registry.addExtension(+[](MLIRContext *ctx, vcix::VCIXDialect *dialect) {
+ dialect->addInterfaces<VCIXDialectLLVMIRTranslationInterface>();
+ });
+}
+
+void mlir::registerVCIXDialectTranslation(MLIRContext &context) {
+ DialectRegistry registry;
+ registerVCIXDialectTranslation(registry);
+ context.appendDialectRegistry(registry);
+}
+
diff --git a/mlir/test/Target/LLVMIR/vcix-rv32.mlir b/mlir/test/Target/LLVMIR/vcix-rv32.mlir
new file mode 100644
index 00000000000000..d9aaf390b462ea
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/vcix-rv32.mlir
@@ -0,0 +1,73 @@
+// RUN: mlir-translate --mlir-to-llvmir %s | FileCheck %s
+
+// CHECK-LABEL: define <vscale x 4 x float> @binary_fv(<vscale x 4 x float> %0, float %1, i32 %2) {
+// CHECK-NEXT: %4 = call <vscale x 4 x float> @llvm.riscv.sf.vc.v.fv.se.nxv4f32.i32.nxv4f32.f32.i32(i32 1, <vscale x 4 x float> %0, float %1, i32 %2)
+// CHECK-NEXT: ret <vscale x 4 x float> %4
+// CHECK-NEXT: }
+llvm.func @binary_fv(%arg0: vector<[4]xf32>, %arg1: f32, %vl: i32) -> vector<[4]xf32> {
+ %0 = "vcix.v.sv"(%arg0, %arg1, %vl) <{opcode = 1 : i32}> : (vector<[4]xf32>, f32, i32) -> vector<[4]xf32>
+ llvm.return %0 : vector<[4]xf32>
+}
+
+// CHECK-LABEL: define <vscale x 4 x float> @binary_xv(<vscale x 4 x float> %0, i32 %1, i32 %2) {
+// CHECK-NEXT: %4 = call <vscale x 4 x float> @llvm.riscv.sf.vc.v.xv.se.nxv4f32.i32.nxv4f32.i32.i32(i32 3, <vscale x 4 x float> %0, i32 %1, i32 %2)
+// CHECK-NEXT: ret <vscale x 4 x float> %4
+// CHECK-NEXT: }
+llvm.func @binary_xv(%arg0: vector<[4]xf32>, %arg1: i32, %vl: i32) -> vector<[4]xf32> {
+ %0 = "vcix.v.sv"(%arg0, %arg1, %vl) <{opcode = 3 : i32}> : (vector<[4]xf32>, i32, i32) -> vector<[4]xf32>
+ llvm.return %0 : vector<[4]xf32>
+}
+
+// CHECK-LABEL: define <vscale x 4 x float> @binary_vv(<vscale x 4 x float> %0, <vscale x 4 x float> %1, i32 %2) {
+// CHECK-NEXT: %4 = call <vscale x 4 x float> @llvm.riscv.sf.vc.v.vv.se.nxv4f32.i32.nxv4f32.nxv4f32.i32(i32 3, <vscale x 4 x float> %0, <vscale x 4 x float> %1, i32 %2)
+// CHECK-NEXT: ret <vscale x 4 x float> %4
+// CHECK-NEXT: }
+llvm.func @binary_vv(%arg0: vector<[4]xf32>, %arg1: vector<[4]xf32>, %vl: i32) -> vector<[4]xf32> {
+ %0 = "vcix.v.sv"(%arg0, %arg1, %vl) <{opcode = 3 : i32}> : (vector<[4]xf32>, vector<[4]xf32>, i32) -> vector<...
[truncated]
|
@llvm/pr-subscribers-mlir-llvm Author: Kolya Panchenko (nikolaypanchenko) ChangesThe changeset extends LLVMIR intrinsics with VCIX intrinsics. Source: https://www.sifive.com/document-file/sifive-vector-coprocessor-interface-vcix-software Patch is 26.93 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/75875.diff 13 Files Affected:
diff --git a/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt b/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
index 8e41fcc05a161e..4c8078c545c735 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
+++ b/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
@@ -71,3 +71,11 @@ mlir_tablegen(ROCDLConversions.inc -gen-llvmir-conversions)
mlir_tablegen(ROCDLOpsAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=rocdl)
mlir_tablegen(ROCDLOpsAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=rocdl)
add_public_tablegen_target(MLIRROCDLConversionsIncGen)
+
+add_mlir_dialect(VCIXOps vcix)
+add_mlir_doc(VCIXOps RVCIXDialect Dialects/ -gen-dialect-doc -dialect=rocdl)
+set(LLVM_TARGET_DEFINITIONS VCIXOps.td)
+mlir_tablegen(VCIXConversions.inc -gen-llvmir-conversions)
+mlir_tablegen(VCIXOpsAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=rocdl)
+mlir_tablegen(VCIXOpsAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=rocdl)
+add_public_tablegen_target(MLIRVCIXConversionsIncGen)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/VCIXDialect.h b/mlir/include/mlir/Dialect/LLVMIR/VCIXDialect.h
new file mode 100644
index 00000000000000..3c911d6bc8677b
--- /dev/null
+++ b/mlir/include/mlir/Dialect/LLVMIR/VCIXDialect.h
@@ -0,0 +1,40 @@
+//===- VCIXDialect.h - MLIR VCIX IR dialect -------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// 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 MLIR_DIALECT_LLVMIR_VCIXDIALECT_H_
+#define MLIR_DIALECT_LLVMIR_VCIXDIALECT_H_
+
+#include "mlir/Bytecode/BytecodeOpInterface.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/Dialect.h"
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/Interfaces/SideEffectInterfaces.h"
+
+///// Ops /////
+#define GET_ATTRDEF_CLASSES
+#include "mlir/Dialect/LLVMIR/VCIXOpsAttributes.h.inc"
+
+#define GET_OP_CLASSES
+#include "mlir/Dialect/LLVMIR/VCIXOps.h.inc"
+
+#include "mlir/Dialect/LLVMIR/VCIXOpsDialect.h.inc"
+
+#endif /* MLIR_DIALECT_LLVMIR_VCIXDIALECT_H_ */
diff --git a/mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td b/mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td
new file mode 100644
index 00000000000000..3f1fa37988c199
--- /dev/null
+++ b/mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td
@@ -0,0 +1,112 @@
+//===-- 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 VCIXIR_OPS
+
+include "mlir/IR/OpBase.td"
+include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
+
+//===----------------------------------------------------------------------===//
+// VCIX dialect definition.
+//===----------------------------------------------------------------------===//
+
+def VCIX_Dialect : Dialect {
+ let name = "vcix";
+ let cppNamespace = "::mlir::vcix";
+ let dependentDialects = ["LLVM::LLVMDialect"];
+ 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
+ }];
+}
+
+// Special version for intrinsic version where int attr is zext to i32 or i64
+// depending on xlen of the target
+def VCIX_VectorOrScalar
+ : AnyTypeOf<[LLVM_AnyVector, I<64>, I<32>, F<16>, F<32>, F<64>]>;
+def VCIX_OpcodeAttr : AnyAttrOf<[I32Attr, I64Attr]>;
+def VCIX_Register : AnyTypeOf<[I32, I64]>;
+def VCIX_ImmAttr : AnyAttrOf<[I32Attr, I64Attr]>;
+def VCIX_VL : AnyTypeOf<[I<64>, I<32>]>;
+
+class VCIX_Op<string mnemonic, list<Trait> traits = []>
+ : LLVM_OpBase<VCIX_Dialect, mnemonic, traits> {
+}
+
+def VCIX_BinaryImmOp
+ : VCIX_Op<"v.iv">,
+ Results<(outs LLVM_AnyVector: $res)>,
+ Arguments<(ins VCIX_OpcodeAttr: $opcode,
+ LLVM_AnyVector: $vs2,
+ VCIX_ImmAttr: $imm,
+ VCIX_Register: $rd,
+ Optional<VCIX_VL>: $vl)> {
+ string llvmBuilder = [{
+ llvm::Type *xlen =getXlenType($opcode, moduleTranslation);
+ llvm::Value *opcodeConst = mlir::LLVM::detail::getLLVMConstant(
+ xlen, $opcode, $_location, moduleTranslation);
+ llvm::Value *immConst = mlir::LLVM::detail::getLLVMConstant(
+ xlen, $imm, $_location, moduleTranslation);
+ VectorType vt = op.getResult().getType().cast<VectorType>();
+ llvm::Value *vl =
+ createVL(builder, $vl, vt, xlen, $_location, moduleTranslation);
+ $res = createIntrinsicCall(
+ builder, llvm::Intrinsic::riscv_sf_vc_v_iv_se,
+ {opcodeConst, $vs2, immConst, vl},
+ {$_resultType, xlen, $vs2->getType(), xlen, xlen});
+ }];
+}
+
+def VCIX_BinaryOp
+ : VCIX_Op<"v.sv">,
+ Results<(outs LLVM_AnyVector: $res)>,
+ Arguments<(ins VCIX_OpcodeAttr: $opcode,
+ LLVM_AnyVector: $vs2,
+ VCIX_VectorOrScalar: $op,
+ Optional<VCIX_VL>: $vl)> {
+ string llvmBuilder = [{
+ llvm::Type *xlen = getXlenType($opcode, moduleTranslation);
+ llvm::Value *opcodeConst = mlir::LLVM::detail::getLLVMConstant(
+ xlen, $opcode, $_location, moduleTranslation);
+ llvm::Intrinsic::ID id;
+ llvm::Type *opType = $op->getType();
+ if (opType->isVectorTy()) {
+ id = llvm::Intrinsic::riscv_sf_vc_v_vv_se;
+ } else if (opType->isIntegerTy()) {
+ id = llvm::Intrinsic::riscv_sf_vc_v_xv_se;
+ } else {
+ id = llvm::Intrinsic::riscv_sf_vc_v_fv_se;
+ }
+ VectorType vt = op.getResult().getType().cast<VectorType>();
+ llvm::Value *vl =
+ createVL(builder, $vl, vt, xlen, $_location, moduleTranslation);
+ $res = createIntrinsicCall(
+ builder, id, {opcodeConst, $vs2, $op, vl},
+ {$_resultType, xlen, $vs2->getType(), $op->getType(), xlen});
+ }];
+}
+
+#endif // VCIXIR_OPS
diff --git a/mlir/include/mlir/Target/LLVMIR/Dialect/All.h b/mlir/include/mlir/Target/LLVMIR/Dialect/All.h
index 0b37e23e45118b..de9d5872cc4546 100644
--- a/mlir/include/mlir/Target/LLVMIR/Dialect/All.h
+++ b/mlir/include/mlir/Target/LLVMIR/Dialect/All.h
@@ -28,6 +28,7 @@
#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/SPIRV/SPIRVToLLVMIRTranslation.h"
+#include "mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/X86Vector/X86VectorToLLVMIRTranslation.h"
namespace mlir {
@@ -48,6 +49,7 @@ static inline void registerAllToLLVMIRTranslations(DialectRegistry ®istry) {
registerOpenMPDialectTranslation(registry);
registerROCDLDialectTranslation(registry);
registerSPIRVDialectTranslation(registry);
+ registerVCIXDialectTranslation(registry);
registerX86VectorDialectTranslation(registry);
// Extension required for translating GPU offloading Ops.
diff --git a/mlir/include/mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h b/mlir/include/mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h
new file mode 100644
index 00000000000000..d84d03a2257928
--- /dev/null
+++ b/mlir/include/mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h
@@ -0,0 +1,31 @@
+//===- VCIXToLLVMIRTranslation.h - VCIX to LLVM IR ------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides registration calls for VCIX dialect to LLVM IR translation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_TARGET_LLVMIR_DIALECT_VCIX_VCIXTOLLVMIRTRANSLATION_H
+#define MLIR_TARGET_LLVMIR_DIALECT_VCIX_VCIXTOLLVMIRTRANSLATION_H
+
+namespace mlir {
+
+class DialectRegistry;
+class MLIRContext;
+
+/// Register the VCIX dialect and the translation from it to the LLVM IR in the
+/// given registry;
+void registerVCIXDialectTranslation(DialectRegistry ®istry);
+
+/// Register the VCIX dialect and the translation from it in the registry
+/// associated with the given context.
+void registerVCIXDialectTranslation(MLIRContext &context);
+
+} // namespace mlir
+
+#endif // MLIR_TARGET_LLVMIR_DIALECT_VCIX_VCIXTOLLVMIRTRANSLATION_H
diff --git a/mlir/lib/Dialect/LLVMIR/CMakeLists.txt b/mlir/lib/Dialect/LLVMIR/CMakeLists.txt
index b00259677697a5..392065b859ee54 100644
--- a/mlir/lib/Dialect/LLVMIR/CMakeLists.txt
+++ b/mlir/lib/Dialect/LLVMIR/CMakeLists.txt
@@ -85,3 +85,25 @@ add_mlir_dialect_library(MLIRROCDLDialect
MLIRLLVMDialect
MLIRSideEffectInterfaces
)
+
+add_mlir_dialect_library(MLIRVCIXDialect
+ IR/VCIXDialect.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/LLVMIR
+
+ DEPENDS
+ MLIRGPUCompilationAttrInterfacesIncGen
+ MLIRVCIXOpsIncGen
+ MLIRVCIXConversionsIncGen
+ intrinsics_gen
+
+ LINK_COMPONENTS
+ AsmParser
+ Core
+
+ LINK_LIBS PUBLIC
+ MLIRIR
+ MLIRLLVMDialect
+ MLIRSideEffectInterfaces
+ )
diff --git a/mlir/lib/Dialect/LLVMIR/IR/VCIXDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/VCIXDialect.cpp
new file mode 100644
index 00000000000000..30ad5bfed1c0b2
--- /dev/null
+++ b/mlir/lib/Dialect/LLVMIR/IR/VCIXDialect.cpp
@@ -0,0 +1,55 @@
+//===- VCIXDialect.cpp - MLIR VCIX ops implementation ---------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the VCIX dialect and its operations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/LLVMIR/VCIXDialect.h"
+
+#include "mlir/Dialect/GPU/IR/CompilationInterfaces.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/DialectImplementation.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/Operation.h"
+#include "llvm/ADT/TypeSwitch.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/SourceMgr.h"
+
+using namespace mlir;
+using namespace vcix;
+
+#include "mlir/Dialect/LLVMIR/VCIXOpsDialect.cpp.inc"
+
+//===----------------------------------------------------------------------===//
+// VCIXDialect initialization, type parsing, and registration.
+//===----------------------------------------------------------------------===//
+
+// TODO: This should be the llvm.rocdl dialect once this is supported.
+void VCIXDialect::initialize() {
+ addOperations<
+#define GET_OP_LIST
+#include "mlir/Dialect/LLVMIR/VCIXOps.cpp.inc"
+ >();
+
+ addAttributes<
+#define GET_ATTRDEF_LIST
+#include "mlir/Dialect/LLVMIR/VCIXOpsAttributes.cpp.inc"
+ >();
+}
+
+#define GET_OP_CLASSES
+#include "mlir/Dialect/LLVMIR/VCIXOps.cpp.inc"
+
+#define GET_ATTRDEF_CLASSES
+#include "mlir/Dialect/LLVMIR/VCIXOpsAttributes.cpp.inc"
diff --git a/mlir/lib/Target/LLVMIR/CMakeLists.txt b/mlir/lib/Target/LLVMIR/CMakeLists.txt
index 94280a2ec9012b..08e10fc3d965bb 100644
--- a/mlir/lib/Target/LLVMIR/CMakeLists.txt
+++ b/mlir/lib/Target/LLVMIR/CMakeLists.txt
@@ -58,6 +58,7 @@ add_mlir_translation_library(MLIRToLLVMIRTranslationRegistration
MLIROpenACCToLLVMIRTranslation
MLIROpenMPToLLVMIRTranslation
MLIRROCDLToLLVMIRTranslation
+ MLIRVCIXToLLVMIRTranslation
MLIRSPIRVToLLVMIRTranslation
)
diff --git a/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt b/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt
index c9d916d8a5d82d..87bed032d2e2da 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt
+++ b/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt
@@ -9,5 +9,6 @@ add_subdirectory(NVVM)
add_subdirectory(OpenACC)
add_subdirectory(OpenMP)
add_subdirectory(ROCDL)
+add_subdirectory(VCIX)
add_subdirectory(SPIRV)
add_subdirectory(X86Vector)
diff --git a/mlir/lib/Target/LLVMIR/Dialect/VCIX/CMakeLists.txt b/mlir/lib/Target/LLVMIR/Dialect/VCIX/CMakeLists.txt
new file mode 100644
index 00000000000000..d2622af16d9383
--- /dev/null
+++ b/mlir/lib/Target/LLVMIR/Dialect/VCIX/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_mlir_translation_library(MLIRVCIXToLLVMIRTranslation
+ VCIXToLLVMIRTranslation.cpp
+
+ DEPENDS
+ MLIRVCIXConversionsIncGen
+
+ LINK_COMPONENTS
+ Core
+
+ LINK_LIBS PUBLIC
+ MLIRIR
+ MLIRLLVMDialect
+ MLIRVCIXDialect
+ MLIRSupport
+ MLIRTargetLLVMIRExport
+ )
diff --git a/mlir/lib/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.cpp
new file mode 100644
index 00000000000000..40aec7eb406782
--- /dev/null
+++ b/mlir/lib/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.cpp
@@ -0,0 +1,89 @@
+//===- VCIXToLLVMIRTranslation.cpp - Translate VCIX to LLVM IR ----------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a translation between the MLIR VCIX dialect and
+// LLVM IR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h"
+#include "mlir/Dialect/LLVMIR/VCIXDialect.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/Operation.h"
+#include "mlir/Target/LLVMIR/ModuleTranslation.h"
+
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicsRISCV.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace mlir;
+using namespace mlir::LLVM;
+using mlir::LLVM::detail::createIntrinsicCall;
+
+/// Infer XLen type from opcode's type. This is done to avoid passing target
+/// option around
+static llvm::Type *getXlenType(Attribute opcodeAttr,
+ LLVM::ModuleTranslation &moduleTranslation) {
+ auto intAttr = opcodeAttr.cast<IntegerAttr>();
+ unsigned xlenWidth = intAttr.getType().cast<IntegerType>().getWidth();
+ return llvm::Type::getIntNTy(moduleTranslation.getLLVMContext(), xlenWidth);
+}
+
+/// Return VL for VCIX intrinsic. If vl was previously set, return it,
+/// otherwise construct a constant using fixed vector type
+static llvm::Value *createVL(llvm::IRBuilderBase &builder, llvm::Value *vl,
+ VectorType vtype, llvm::Type *xlen, Location loc,
+ LLVM::ModuleTranslation &moduleTranslation) {
+ if (vl) {
+ assert(vtype.isScalable() &&
+ "vl parameter must be set for scalable vectors");
+ return builder.CreateZExtOrTrunc(vl, xlen);
+ }
+
+ assert(vtype.getRank() == 1 && "Only 1-d fixed vectors are supported");
+ return mlir::LLVM::detail::getLLVMConstant(
+ xlen,
+ IntegerAttr::get(IntegerType::get(&moduleTranslation.getContext(), 64),
+ vtype.getShape()[0]),
+ loc, moduleTranslation);
+}
+
+namespace {
+/// Implementation of the dialect interface that converts operations belonging
+/// to the VCIX dialect to LLVM IR.
+class VCIXDialectLLVMIRTranslationInterface
+ : public LLVMTranslationDialectInterface {
+public:
+ using LLVMTranslationDialectInterface::LLVMTranslationDialectInterface;
+
+ /// Translates the given operation to LLVM IR using the provided IR builder
+ /// and saving the state in `moduleTranslation`.
+ LogicalResult
+ convertOperation(Operation *op, llvm::IRBuilderBase &builder,
+ LLVM::ModuleTranslation &moduleTranslation) const final {
+ Operation &opInst = *op;
+#include "mlir/Dialect/LLVMIR/VCIXConversions.inc"
+
+ return failure();
+ }
+};
+} // namespace
+
+void mlir::registerVCIXDialectTranslation(DialectRegistry ®istry) {
+ registry.insert<vcix::VCIXDialect>();
+ registry.addExtension(+[](MLIRContext *ctx, vcix::VCIXDialect *dialect) {
+ dialect->addInterfaces<VCIXDialectLLVMIRTranslationInterface>();
+ });
+}
+
+void mlir::registerVCIXDialectTranslation(MLIRContext &context) {
+ DialectRegistry registry;
+ registerVCIXDialectTranslation(registry);
+ context.appendDialectRegistry(registry);
+}
+
diff --git a/mlir/test/Target/LLVMIR/vcix-rv32.mlir b/mlir/test/Target/LLVMIR/vcix-rv32.mlir
new file mode 100644
index 00000000000000..d9aaf390b462ea
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/vcix-rv32.mlir
@@ -0,0 +1,73 @@
+// RUN: mlir-translate --mlir-to-llvmir %s | FileCheck %s
+
+// CHECK-LABEL: define <vscale x 4 x float> @binary_fv(<vscale x 4 x float> %0, float %1, i32 %2) {
+// CHECK-NEXT: %4 = call <vscale x 4 x float> @llvm.riscv.sf.vc.v.fv.se.nxv4f32.i32.nxv4f32.f32.i32(i32 1, <vscale x 4 x float> %0, float %1, i32 %2)
+// CHECK-NEXT: ret <vscale x 4 x float> %4
+// CHECK-NEXT: }
+llvm.func @binary_fv(%arg0: vector<[4]xf32>, %arg1: f32, %vl: i32) -> vector<[4]xf32> {
+ %0 = "vcix.v.sv"(%arg0, %arg1, %vl) <{opcode = 1 : i32}> : (vector<[4]xf32>, f32, i32) -> vector<[4]xf32>
+ llvm.return %0 : vector<[4]xf32>
+}
+
+// CHECK-LABEL: define <vscale x 4 x float> @binary_xv(<vscale x 4 x float> %0, i32 %1, i32 %2) {
+// CHECK-NEXT: %4 = call <vscale x 4 x float> @llvm.riscv.sf.vc.v.xv.se.nxv4f32.i32.nxv4f32.i32.i32(i32 3, <vscale x 4 x float> %0, i32 %1, i32 %2)
+// CHECK-NEXT: ret <vscale x 4 x float> %4
+// CHECK-NEXT: }
+llvm.func @binary_xv(%arg0: vector<[4]xf32>, %arg1: i32, %vl: i32) -> vector<[4]xf32> {
+ %0 = "vcix.v.sv"(%arg0, %arg1, %vl) <{opcode = 3 : i32}> : (vector<[4]xf32>, i32, i32) -> vector<[4]xf32>
+ llvm.return %0 : vector<[4]xf32>
+}
+
+// CHECK-LABEL: define <vscale x 4 x float> @binary_vv(<vscale x 4 x float> %0, <vscale x 4 x float> %1, i32 %2) {
+// CHECK-NEXT: %4 = call <vscale x 4 x float> @llvm.riscv.sf.vc.v.vv.se.nxv4f32.i32.nxv4f32.nxv4f32.i32(i32 3, <vscale x 4 x float> %0, <vscale x 4 x float> %1, i32 %2)
+// CHECK-NEXT: ret <vscale x 4 x float> %4
+// CHECK-NEXT: }
+llvm.func @binary_vv(%arg0: vector<[4]xf32>, %arg1: vector<[4]xf32>, %vl: i32) -> vector<[4]xf32> {
+ %0 = "vcix.v.sv"(%arg0, %arg1, %vl) <{opcode = 3 : i32}> : (vector<[4]xf32>, vector<[4]xf32>, i32) -> vector<...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Taking a quick look for now. I think we need to add some conversion testing, at least under the test
folder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I didn't mean to approve :)
4e9e7e8
to
1dbcab8
Compare
Thanks. Added few more tests, but if you do have in mind to test something else I'll be glad to add such tests |
1dbcab8
to
0893fa4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went over it again. It looks mostly ready!
Regarding testing, I meant you could add a test conversion pass to make sure this is a bit more exercised. You can go to mlir/test/lib/Conversion/VectorToVCIX (or any other dialect) and create a TestVectorToVCIXPass there that does a dummy conversion from arbitrary vector ops to vcix ops. Then you can create a test file using that pass under mlir/test/Conversion/VectorToVCIX. That should be all!
// | ||
// The file defines the basic operations for the VCIX dialect. | ||
// | ||
// The SiFive Vector Coprocessor Interface (VCIX) provides a flexible mechanism |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any official RISC-V ratification that we should mention/point to here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VCIX is a custom extension. The official link is given at the line 18
mlir/include/mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h
Outdated
Show resolved
Hide resolved
0893fa4
to
bb489a9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the tests! They look great! LGTM! I just added a bunch of nits. Feel free to address them before submitting.
Thanks!
@@ -0,0 +1,148 @@ | |||
// RUN: mlir-translate --mlir-to-llvmir %s | FileCheck %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if --split-input-file
is supported by mlir-translate
but please try to add it as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it does have this option. Will add it and delimiters to these tests
mlir/test/lib/Conversion/MathToVCIX/TestMathToVCIXConversion.cpp
Outdated
Show resolved
Hide resolved
mlir/test/lib/Conversion/MathToVCIX/TestMathToVCIXConversion.cpp
Outdated
Show resolved
Hide resolved
mlir/test/lib/Conversion/MathToVCIX/TestMathToVCIXConversion.cpp
Outdated
Show resolved
Hide resolved
mlir/test/lib/Conversion/MathToVCIX/TestMathToVCIXConversion.cpp
Outdated
Show resolved
Hide resolved
mlir/lib/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.cpp
Outdated
Show resolved
Hide resolved
mlir/lib/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.cpp
Outdated
Show resolved
Hide resolved
Mnemonic funct6 vm rs2 rs1 funct3 rd Destination Sources | ||
sf.vc.v.iv 0010-- 0 vs2 simm 011 vd vector vd simm[4:0], vector vs2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how this will look like on the web. You may want to consider a markdown table?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's good suggestion. I'll rewrite it to markdown
The changeset extends LLVMIR intrinsics with VCIX intrinsics. The VCIX intrinsics allow MLIR users to interact with RISC-V co-processors that are compatible with `XSfvcp` extension Source: https://www.sifive.com/document-file/sifive-vector-coprocessor-interface-vcix-software
bb489a9
to
8a6c546
Compare
@dcaballe thanks for the review. |
The changeset extends LLVMIR intrinsics with VCIX intrinsics.
The VCIX intrinsics allow MLIR users to interact with RISC-V co-processors that are compatible with
XSfvcp
extensionSource: https://www.sifive.com/document-file/sifive-vector-coprocessor-interface-vcix-software