These commits set up the skeleton for SPIR-V to LLVM dialect conversion.
I created SPIR-V to LLVM pass, registered it in Passes.td, InitAllPasses.h.
Added a pattern for `spv.BitwiseAndOp` and tests for it. Integer, float
and vector types are converted through LLVMTypeConverter.
Differential Revision: https://reviews.llvm.org/D81100
}
//===----------------------------------------------------------------------===//
+// SPIRVToLLVM
+//===----------------------------------------------------------------------===//
+
+def ConvertSPIRVToLLVM : Pass<"convert-spirv-to-llvm", "ModuleOp"> {
+ let summary = "Convert SPIR-V dialect to LLVM dialect";
+ let constructor = "mlir::createConvertSPIRVToLLVMPass()";
+}
+
+//===----------------------------------------------------------------------===//
// StandardToLLVM
//===----------------------------------------------------------------------===//
--- /dev/null
+//===- ConvertSPIRVToLLVM.h - Convert SPIR-V to LLVM 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Provides patterns to convert SPIR-V dialect to LLVM dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVM_H
+#define MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVM_H
+
+#include "mlir/Transforms/DialectConversion.h"
+
+namespace mlir {
+class LLVMTypeConverter;
+class MLIRContext;
+class ModuleOp;
+
+/// Populates the given list with patterns that convert from SPIR-V to LLVM.
+void populateSPIRVToLLVMConversionPatterns(MLIRContext *context,
+ LLVMTypeConverter &typeConverter,
+ OwningRewritePatternList &patterns);
+
+} // namespace mlir
+
+#endif // MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVM_H
--- /dev/null
+//===- ConvertSPIRVToLLVMPass.h - SPIR-V dialect to LLVM pass ---*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Provides a pass to lower from SPIR-V dialect to LLVM dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVMPASS_H
+#define MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVMPASS_H
+
+#include <memory>
+
+namespace mlir {
+class ModuleOp;
+template <typename T>
+class OperationPass;
+
+/// Creates a pass to convert SPIR-V operations to the LLVMIR dialect.
+std::unique_ptr<OperationPass<ModuleOp>> createConvertSPIRVToLLVMPass();
+
+} // namespace mlir
+
+#endif // MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVMPASS_H_
namespace mlir {
class LLVMTypeConverter;
class ModuleOp;
-template <typename T> class OperationPass;
+template <typename T>
+class OperationPass;
/// Collect a set of patterns to convert from Vector contractions to LLVM Matrix
/// Intrinsics. To lower to assembly, the LLVM flag -lower-matrix-intrinsics
#include "mlir/Conversion/LinalgToStandard/LinalgToStandard.h"
#include "mlir/Conversion/SCFToGPU/SCFToGPUPass.h"
#include "mlir/Conversion/SCFToStandard/SCFToStandard.h"
+#include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h"
#include "mlir/Conversion/ShapeToStandard/ShapeToStandard.h"
#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
#include "mlir/Conversion/StandardToSPIRV/ConvertStandardToSPIRVPass.h"
add_subdirectory(SCFToGPU)
add_subdirectory(SCFToStandard)
add_subdirectory(ShapeToStandard)
+add_subdirectory(SPIRVToLLVM)
add_subdirectory(StandardToLLVM)
add_subdirectory(StandardToSPIRV)
add_subdirectory(VectorToLLVM)
--- /dev/null
+add_mlir_conversion_library(MLIRSPIRVToLLVM
+ ConvertSPIRVToLLVM.cpp
+ ConvertSPIRVToLLVMPass.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/SPIRVToLLVM
+
+ DEPENDS
+ MLIRConversionPassIncGen
+ intrinsics_gen
+
+ LINK_LIBS PUBLIC
+ MLIRSPIRV
+ MLIRLLVMIR
+ MLIRStandardToLLVM
+ MLIRIR
+ MLIRTransforms
+ )
--- /dev/null
+//===- ConvertSPIRVToLLVM.cpp - SPIR-V dialect to LLVM dialect conversion -===//
+//
+// 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 patterns to convert SPIR-V dialect to LLVM dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h"
+#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h"
+#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/SPIRV/SPIRVDialect.h"
+#include "mlir/Dialect/SPIRV/SPIRVOps.h"
+#include "mlir/Dialect/StandardOps/IR/Ops.h"
+#include "mlir/IR/Module.h"
+#include "mlir/IR/PatternMatch.h"
+#include "mlir/Support/LogicalResult.h"
+#include "mlir/Transforms/DialectConversion.h"
+
+using namespace mlir;
+
+namespace {
+
+class BitwiseAndOpConversion : public ConvertToLLVMPattern {
+public:
+ explicit BitwiseAndOpConversion(MLIRContext *context,
+ LLVMTypeConverter &typeConverter)
+ : ConvertToLLVMPattern(spirv::BitwiseAndOp::getOperationName(), context,
+ typeConverter) {}
+
+ LogicalResult
+ matchAndRewrite(Operation *op, ArrayRef<Value> operands,
+ ConversionPatternRewriter &rewriter) const override {
+ auto bitwiseAndOp = cast<spirv::BitwiseAndOp>(op);
+ auto dstType = typeConverter.convertType(bitwiseAndOp.getType());
+ if (!dstType)
+ return failure();
+ rewriter.replaceOpWithNewOp<LLVM::AndOp>(bitwiseAndOp, dstType, operands);
+ return success();
+ }
+};
+} // namespace
+
+void mlir::populateSPIRVToLLVMConversionPatterns(
+ MLIRContext *context, LLVMTypeConverter &typeConverter,
+ OwningRewritePatternList &patterns) {
+ patterns.insert<BitwiseAndOpConversion>(context, typeConverter);
+}
--- /dev/null
+//===- ConvertSPIRVToLLVMPass.cpp - Convert SPIR-V ops to LLVM ops --------===//
+//
+// 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 pass to convert MLIR SPIR-V ops into LLVM ops
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h"
+#include "../PassDetail.h"
+#include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h"
+#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h"
+#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/SPIRV/SPIRVDialect.h"
+
+using namespace mlir;
+
+namespace {
+/// A pass converting MLIR SPIR-V operations into LLVM dialect.
+class ConvertSPIRVToLLVMPass
+ : public ConvertSPIRVToLLVMBase<ConvertSPIRVToLLVMPass> {
+ void runOnOperation() override;
+};
+} // namespace
+
+void ConvertSPIRVToLLVMPass::runOnOperation() {
+ MLIRContext *context = &getContext();
+ ModuleOp module = getOperation();
+ LLVMTypeConverter converter(&getContext());
+
+ OwningRewritePatternList patterns;
+ populateSPIRVToLLVMConversionPatterns(context, converter, patterns);
+
+ // Currently pulls in Std to LLVM conversion patterns
+ // that help with testing. This allows to convert
+ // function arguments to LLVM.
+ populateStdToLLVMConversionPatterns(converter, patterns);
+
+ ConversionTarget target(getContext());
+ target.addIllegalDialect<spirv::SPIRVDialect>();
+ target.addLegalDialect<LLVM::LLVMDialect>();
+
+ if (failed(applyPartialConversion(module, target, patterns, &converter)))
+ signalPassFailure();
+}
+
+std::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertSPIRVToLLVMPass() {
+ return std::make_unique<ConvertSPIRVToLLVMPass>();
+}
--- /dev/null
+// RUN: mlir-opt -convert-spirv-to-llvm %s | FileCheck %s
+
+func @bitwise_and_scalar(%arg0: i32, %arg1: i32) {
+ // CHECK: %{{.*}} = llvm.and %{{.*}}, %{{.*}} : !llvm.i32
+ %0 = spv.BitwiseAnd %arg0, %arg1 : i32
+ return
+}
+
+func @bitwise_and_vector(%arg0: vector<4xi64>, %arg1: vector<4xi64>) {
+ // CHECK: %{{.*}} = llvm.and %{{.*}}, %{{.*}} : !llvm<"<4 x i64>">
+ %0 = spv.BitwiseAnd %arg0, %arg1 : vector<4xi64>
+ return
+}