diff --git a/mlir/include/mlir/Conversion/Passes.h b/mlir/include/mlir/Conversion/Passes.h --- a/mlir/include/mlir/Conversion/Passes.h +++ b/mlir/include/mlir/Conversion/Passes.h @@ -57,6 +57,7 @@ #include "mlir/Conversion/TosaToLinalg/TosaToLinalg.h" #include "mlir/Conversion/TosaToSCF/TosaToSCF.h" #include "mlir/Conversion/TosaToTensor/TosaToTensor.h" +#include "mlir/Conversion/UBToLLVM/UBToLLVM.h" #include "mlir/Conversion/VectorToArmSME/VectorToArmSME.h" #include "mlir/Conversion/VectorToGPU/VectorToGPU.h" #include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h" diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td --- a/mlir/include/mlir/Conversion/Passes.td +++ b/mlir/include/mlir/Conversion/Passes.td @@ -1037,6 +1037,23 @@ let constructor = "tosa::createTosaToTensor()"; } +//===----------------------------------------------------------------------===// +// UBToLLVM +//===----------------------------------------------------------------------===// + +def UBToLLVMConversionPass : Pass<"convert-ub-to-llvm"> { + let summary = "Convert UB dialect to LLVM dialect"; + let description = [{ + This pass converts supported UB ops to LLVM dialect instructions. + }]; + let dependentDialects = ["LLVM::LLVMDialect"]; + let options = [ + Option<"indexBitwidth", "index-bitwidth", "unsigned", + /*default=kDeriveIndexBitwidthFromDataLayout*/"0", + "Bitwidth of the index type, 0 to use size of machine word">, + ]; +} + //===----------------------------------------------------------------------===// // VectorToGPU //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/Conversion/UBToLLVM/UBToLLVM.h b/mlir/include/mlir/Conversion/UBToLLVM/UBToLLVM.h new file mode 100644 --- /dev/null +++ b/mlir/include/mlir/Conversion/UBToLLVM/UBToLLVM.h @@ -0,0 +1,29 @@ +//===- UBToLLVM.h - UB to LLVM dialect conversion ---------------*- 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_CONVERSION_UBTOLLVM_UBLLVM_H +#define MLIR_CONVERSION_UBTOLLVM_UBLLVM_H + +#include + +namespace mlir { + +class LLVMTypeConverter; +class RewritePatternSet; +class Pass; + +#define GEN_PASS_DECL_UBTOLLVMCONVERSIONPASS +#include "mlir/Conversion/Passes.h.inc" + +namespace ub { +void populateUBToLLVMConversionPatterns(LLVMTypeConverter &converter, + RewritePatternSet &patterns); +} // namespace ub +} // namespace mlir + +#endif // MLIR_CONVERSION_UBTOLLVM_UBLLVM_H diff --git a/mlir/lib/Conversion/CMakeLists.txt b/mlir/lib/Conversion/CMakeLists.txt --- a/mlir/lib/Conversion/CMakeLists.txt +++ b/mlir/lib/Conversion/CMakeLists.txt @@ -6,8 +6,8 @@ add_subdirectory(ArmNeon2dToIntr) add_subdirectory(AsyncToLLVM) add_subdirectory(BufferizationToMemRef) -add_subdirectory(ComplexToLLVM) add_subdirectory(ComplexToLibm) +add_subdirectory(ComplexToLLVM) add_subdirectory(ComplexToSPIRV) add_subdirectory(ComplexToStandard) add_subdirectory(ControlFlowToLLVM) @@ -47,8 +47,9 @@ add_subdirectory(TosaToLinalg) add_subdirectory(TosaToSCF) add_subdirectory(TosaToTensor) +add_subdirectory(UBToLLVM) add_subdirectory(VectorToArmSME) -add_subdirectory(VectorToLLVM) add_subdirectory(VectorToGPU) +add_subdirectory(VectorToLLVM) add_subdirectory(VectorToSCF) add_subdirectory(VectorToSPIRV) diff --git a/mlir/lib/Conversion/UBToLLVM/CMakeLists.txt b/mlir/lib/Conversion/UBToLLVM/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/mlir/lib/Conversion/UBToLLVM/CMakeLists.txt @@ -0,0 +1,17 @@ +add_mlir_conversion_library(MLIRUBToLLVM + UBToLLVM.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/UBToLLVM + + DEPENDS + MLIRConversionPassIncGen + + LINK_COMPONENTS + Core + + LINK_LIBS PUBLIC + MLIRLLVMCommonConversion + MLIRLLVMDialect + MLIRUBDialect + ) diff --git a/mlir/lib/Conversion/UBToLLVM/UBToLLVM.cpp b/mlir/lib/Conversion/UBToLLVM/UBToLLVM.cpp new file mode 100644 --- /dev/null +++ b/mlir/lib/Conversion/UBToLLVM/UBToLLVM.cpp @@ -0,0 +1,93 @@ +//===- UBToLLVM.cpp - UB 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 +// +//===----------------------------------------------------------------------===// + +#include "mlir/Conversion/UBToLLVM/UBToLLVM.h" + +#include "mlir/Conversion/LLVMCommon/ConversionTarget.h" +#include "mlir/Conversion/LLVMCommon/Pattern.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/Dialect/UB/IR/UBOps.h" +#include "mlir/IR/TypeUtilities.h" +#include "mlir/Pass/Pass.h" + +namespace mlir { +#define GEN_PASS_DEF_UBTOLLVMCONVERSIONPASS +#include "mlir/Conversion/Passes.h.inc" +} // namespace mlir + +using namespace mlir; + +namespace { + +struct PoisonOpLowering : public ConvertOpToLLVMPattern { + using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; + + LogicalResult + matchAndRewrite(ub::PoisonOp op, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override; +}; + +} // namespace + +//===----------------------------------------------------------------------===// +// PoisonOpLowering +//===----------------------------------------------------------------------===// + +LogicalResult +PoisonOpLowering::matchAndRewrite(ub::PoisonOp op, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const { + Type origType = op.getType(); + if (!origType.isIntOrIndexOrFloat()) + return rewriter.notifyMatchFailure( + op, [&](Diagnostic &diag) { diag << "unsupported type " << origType; }); + + Type resType = getTypeConverter()->convertType(origType); + if (!resType) + return rewriter.notifyMatchFailure(op, [&](Diagnostic &diag) { + diag << "failed to convert result type " << origType; + }); + + rewriter.replaceOpWithNewOp(op, resType); + return success(); +} + +//===----------------------------------------------------------------------===// +// Pass Definition +//===----------------------------------------------------------------------===// + +namespace { +struct UBToLLVMConversionPass + : public impl::UBToLLVMConversionPassBase { + using Base::Base; + + void runOnOperation() override { + LLVMConversionTarget target(getContext()); + RewritePatternSet patterns(&getContext()); + + LowerToLLVMOptions options(&getContext()); + if (indexBitwidth != kDeriveIndexBitwidthFromDataLayout) + options.overrideIndexBitwidth(indexBitwidth); + + LLVMTypeConverter converter(&getContext(), options); + mlir::ub::populateUBToLLVMConversionPatterns(converter, patterns); + + if (failed(applyPartialConversion(getOperation(), target, + std::move(patterns)))) + signalPassFailure(); + } +}; +} // namespace + +//===----------------------------------------------------------------------===// +// Pattern Population +//===----------------------------------------------------------------------===// + +void mlir::ub::populateUBToLLVMConversionPatterns(LLVMTypeConverter &converter, + RewritePatternSet &patterns) { + patterns.add(converter); +} diff --git a/mlir/test/Conversion/UBToLLVM/ub-to-llvm.mlir b/mlir/test/Conversion/UBToLLVM/ub-to-llvm.mlir new file mode 100644 --- /dev/null +++ b/mlir/test/Conversion/UBToLLVM/ub-to-llvm.mlir @@ -0,0 +1,12 @@ +// RUN: mlir-opt -pass-pipeline="builtin.module(func.func(convert-ub-to-llvm))" %s -split-input-file | FileCheck %s + +// CHECK-LABEL: @check_poison +func.func @check_poison() { +// CHECK: {{.*}} = llvm.mlir.poison : i64 + %0 = ub.poison : index +// CHECK: {{.*}} = llvm.mlir.poison : i16 + %1 = ub.poison : i16 +// CHECK: {{.*}} = llvm.mlir.poison : f64 + %2 = ub.poison : f64 + return +}