diff --git a/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp b/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp index 4f9a602233536..7eedd3a8769ff 100644 --- a/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp +++ b/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp @@ -82,6 +82,32 @@ struct ConvertStore final : public OpConversionPattern { } }; +struct ConvertAlloca final : public OpConversionPattern { + using OpConversionPattern::OpConversionPattern; + + LogicalResult + matchAndRewrite(memref::AllocaOp op, OpAdaptor operands, + ConversionPatternRewriter &rewriter) const override { + + if (!op.getType().hasStaticShape()) { + return rewriter.notifyMatchFailure( + op.getLoc(), "cannot transform alloca with dynamic shape"); + } + + if (op.getAlignment().value_or(1) > 1) { + // TODO: Allow alignment if it is not more than the natural alignment + // of the C array. + return rewriter.notifyMatchFailure( + op.getLoc(), "cannot transform alloca with alignment requirement"); + } + + auto resultTy = getTypeConverter()->convertType(op.getType()); + auto noInit = emitc::OpaqueAttr::get(getContext(), ""); + rewriter.replaceOpWithNewOp(op, resultTy, noInit); + return success(); + } +}; + struct ConvertMemRefToEmitCPass : public impl::ConvertMemRefToEmitCBase { void runOnOperation() override { @@ -135,8 +161,8 @@ void mlir::populateMemRefToEmitCConversionPatterns(RewritePatternSet &patterns, converter); populateCallOpTypeConversionPattern(patterns, converter); populateReturnOpTypeConversionPattern(patterns, converter); - patterns.add(converter, patterns.getContext()); - patterns.add(converter, patterns.getContext()); + patterns.add(converter, + patterns.getContext()); } std::unique_ptr> mlir::createConvertMemRefToEmitCPass() { diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-to-emit-failed.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emit-failed.mlir index 56d48bef3e1b3..2903fbffccb02 100644 --- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emit-failed.mlir +++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emit-failed.mlir @@ -22,3 +22,20 @@ func.func @memref_op(%arg0 : memref<2x4xf32>) { memref.copy %arg0, %arg0 : memref<2x4xf32> to memref<2x4xf32> return } + +// ----- + +func.func @alloca_with_dynamic_shape() { + %0 = index.constant 1 + // expected-error@+1 {{failed to legalize operation 'memref.alloca' that was explicitly marked illegal}} + %1 = memref.alloca(%0) : memref<4x?xf32> + return +} + +// ----- + +func.func @alloca_with_alignment() { + // expected-error@+1 {{failed to legalize operation 'memref.alloca' that was explicitly marked illegal}} + %1 = memref.alloca() {alignment = 64 : i64}: memref<4xf32> + return +} diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir index b41e27388f2c8..f3bc5a5124bf0 100644 --- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir +++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir @@ -36,3 +36,12 @@ func.func @memref_load_store(%in: memref<4x8xf32>, %out: memref<3x5xf32>, %i: in memref.store %0, %out[%i, %j] : memref<3x5xf32> return } + +// ----- + +// CHECK-LABEL: alloca +func.func @alloca() { + // CHECK "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.array<4x8xf32> + %0 = memref.alloca() : memref<4x8xf32> + return +}