[Mlir-commits] [mlir] [mlir][emitc] Add type conversions to EmitC types to FuncToEmitC, MemRefToEmitC (PR #134096)
Corentin Ferry
llvmlistbot at llvm.org
Wed Apr 2 08:19:01 PDT 2025
https://github.com/cferry-AMD created https://github.com/llvm/llvm-project/pull/134096
PR #93155 introduced EmitC `size_t`, `ptrdiff_t`, `ssize_t` types. Conversion passes `ArithToEmitC` and `SCFToEmitC` already make use of these types, but `FuncToEmitC` and `MemRefToEmitC` do not yet. This PR introduces EmitC type conversion into the latter two passes.
While `MemRefToEmitC` is pretty straightforward, `FuncToEmitC` required changes to:
* the call op lowering: the results of the op need to be converted,
* the function op lowering: the function signature (arguments and results) needs to be converted.
>From fd5a3a3e3ac9924a9a4213d13558ac6aafcad305 Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Tue, 21 May 2024 16:14:17 +0200
Subject: [PATCH 1/5] Use EmitC index types in all passes creating EmitC
---
.../mlir/Conversion/FuncToEmitC/FuncToEmitC.h | 4 +-
.../Conversion/FuncToEmitC/FuncToEmitC.cpp | 45 ++++++++++++++++---
.../FuncToEmitC/FuncToEmitCPass.cpp | 10 ++++-
.../MemRefToEmitC/MemRefToEmitCPass.cpp | 2 +
.../Conversion/FuncToEmitC/func-to-emitc.mlir | 30 +++++++++++++
.../MemRefToEmitC/memref-to-emitc.mlir | 22 +++++++++
.../Conversion/SCFToEmitC/nest-for-if.mlir | 33 ++++++++++++++
7 files changed, 137 insertions(+), 9 deletions(-)
create mode 100644 mlir/test/Conversion/SCFToEmitC/nest-for-if.mlir
diff --git a/mlir/include/mlir/Conversion/FuncToEmitC/FuncToEmitC.h b/mlir/include/mlir/Conversion/FuncToEmitC/FuncToEmitC.h
index 5c7f87e470306..ac6fe2da7d42f 100644
--- a/mlir/include/mlir/Conversion/FuncToEmitC/FuncToEmitC.h
+++ b/mlir/include/mlir/Conversion/FuncToEmitC/FuncToEmitC.h
@@ -9,10 +9,12 @@
#ifndef MLIR_CONVERSION_FUNCTOEMITC_FUNCTOEMITC_H
#define MLIR_CONVERSION_FUNCTOEMITC_FUNCTOEMITC_H
+#include "mlir/Transforms/DialectConversion.h"
namespace mlir {
class RewritePatternSet;
-void populateFuncToEmitCPatterns(RewritePatternSet &patterns);
+void populateFuncToEmitCPatterns(RewritePatternSet &patterns,
+ TypeConverter &typeConverter);
} // namespace mlir
#endif // MLIR_CONVERSION_FUNCTOEMITC_FUNCTOEMITC_H
diff --git a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
index 53b79839da04c..f2ea9add77d87 100644
--- a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
+++ b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
@@ -36,9 +36,17 @@ class CallOpConversion final : public OpConversionPattern<func::CallOp> {
return rewriter.notifyMatchFailure(
callOp, "only functions with zero or one result can be converted");
- rewriter.replaceOpWithNewOp<emitc::CallOp>(callOp, callOp.getResultTypes(),
- adaptor.getOperands(),
- callOp->getAttrs());
+ // Convert the original function results.
+ Type resultTy = nullptr;
+ if (callOp.getNumResults()) {
+ resultTy = typeConverter->convertType(callOp.getResult(0).getType());
+ if (!resultTy)
+ return rewriter.notifyMatchFailure(
+ callOp, "function return type conversion failed");
+ }
+
+ rewriter.replaceOpWithNewOp<emitc::CallOp>(
+ callOp, resultTy, adaptor.getOperands(), callOp->getAttrs());
return success();
}
@@ -52,13 +60,34 @@ class FuncOpConversion final : public OpConversionPattern<func::FuncOp> {
matchAndRewrite(func::FuncOp funcOp, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
- if (funcOp.getFunctionType().getNumResults() > 1)
+ FunctionType type = funcOp.getFunctionType();
+ if (!type)
+ return failure();
+
+ if (type.getNumResults() > 1)
return rewriter.notifyMatchFailure(
funcOp, "only functions with zero or one result can be converted");
+ const TypeConverter *converter = getTypeConverter();
+
+ // Convert function signature
+ TypeConverter::SignatureConversion signatureConversion(type.getNumInputs());
+ SmallVector<Type, 1> convertedResults;
+ if (failed(converter->convertSignatureArgs(type.getInputs(),
+ signatureConversion)) ||
+ failed(converter->convertTypes(type.getResults(), convertedResults)) ||
+ failed(rewriter.convertRegionTypes(&funcOp.getFunctionBody(),
+ *converter, &signatureConversion)))
+ return rewriter.notifyMatchFailure(funcOp, "signature conversion failed");
+
+ // Convert the function type
+ auto convertedFunctionType = FunctionType::get(
+ rewriter.getContext(), signatureConversion.getConvertedTypes(),
+ convertedResults);
+
// Create the converted `emitc.func` op.
emitc::FuncOp newFuncOp = rewriter.create<emitc::FuncOp>(
- funcOp.getLoc(), funcOp.getName(), funcOp.getFunctionType());
+ funcOp.getLoc(), funcOp.getName(), convertedFunctionType);
// Copy over all attributes other than the function name and type.
for (const auto &namedAttr : funcOp->getAttrs()) {
@@ -112,8 +141,10 @@ class ReturnOpConversion final : public OpConversionPattern<func::ReturnOp> {
// Pattern population
//===----------------------------------------------------------------------===//
-void mlir::populateFuncToEmitCPatterns(RewritePatternSet &patterns) {
+void mlir::populateFuncToEmitCPatterns(RewritePatternSet &patterns,
+ TypeConverter &typeConverter) {
MLIRContext *ctx = patterns.getContext();
- patterns.add<CallOpConversion, FuncOpConversion, ReturnOpConversion>(ctx);
+ patterns.add<CallOpConversion, FuncOpConversion, ReturnOpConversion>(
+ typeConverter, ctx);
}
diff --git a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitCPass.cpp b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitCPass.cpp
index 0b97f2641ad08..94e324adfc466 100644
--- a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitCPass.cpp
+++ b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitCPass.cpp
@@ -14,6 +14,7 @@
#include "mlir/Conversion/FuncToEmitC/FuncToEmitC.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
+#include "mlir/Dialect/EmitC/Transforms/TypeConversions.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Transforms/DialectConversion.h"
@@ -33,13 +34,20 @@ struct ConvertFuncToEmitC
} // namespace
void ConvertFuncToEmitC::runOnOperation() {
+ TypeConverter typeConverter;
+ // Fallback converter
+ // See note https://mlir.llvm.org/docs/DialectConversion/#type-converter
+ // Type converters are called most to least recently inserted
+ typeConverter.addConversion([](Type t) { return t; });
+ populateEmitCSizeTTypeConversions(typeConverter);
+
ConversionTarget target(getContext());
target.addLegalDialect<emitc::EmitCDialect>();
target.addIllegalOp<func::CallOp, func::FuncOp, func::ReturnOp>();
RewritePatternSet patterns(&getContext());
- populateFuncToEmitCPatterns(patterns);
+ populateFuncToEmitCPatterns(patterns, typeConverter);
if (failed(
applyPartialConversion(getOperation(), target, std::move(patterns))))
diff --git a/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitCPass.cpp b/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitCPass.cpp
index 33097c71e70b1..95b7765129085 100644
--- a/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitCPass.cpp
+++ b/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitCPass.cpp
@@ -14,6 +14,7 @@
#include "mlir/Conversion/MemRefToEmitC/MemRefToEmitC.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
+#include "mlir/Dialect/EmitC/Transforms/TypeConversions.h"
#include "mlir/Dialect/MemRef/IR/MemRef.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Transforms/DialectConversion.h"
@@ -39,6 +40,7 @@ struct ConvertMemRefToEmitCPass
});
populateMemRefToEmitCTypeConversion(converter);
+ populateEmitCSizeTTypeConversions(converter);
auto materializeAsUnrealizedCast = [](OpBuilder &builder, Type resultType,
ValueRange inputs,
diff --git a/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir b/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
index bd48886ed739e..046073eb30306 100644
--- a/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
+++ b/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
@@ -74,3 +74,33 @@ func.func @call() {
call @return_void() : () -> ()
return
}
+
+// -----
+
+// CHECK-LABEL: emitc.func @use_index
+// CHECK-SAME: (%[[Arg0:.*]]: !emitc.size_t) -> !emitc.size_t
+// CHECK: emitc.return %[[Arg0]] : !emitc.size_t
+func.func @use_index(%arg0: index) -> index {
+ return %arg0 : index
+}
+
+// -----
+
+// CHECK-LABEL: emitc.func private @prototype_index(!emitc.size_t) -> !emitc.size_t attributes {specifiers = ["extern"]}
+func.func private @prototype_index(%arg0: index) -> index
+
+// CHECK-LABEL: emitc.func @call(%arg0: !emitc.size_t) -> !emitc.size_t
+// CHECK-NEXT: %0 = emitc.call @prototype_index(%arg0) : (!emitc.size_t) -> !emitc.size_t
+// CHECK-NEXT: emitc.return %0 : !emitc.size_t
+func.func @call(%arg0: index) -> index {
+ %0 = call @prototype_index(%arg0) : (index) -> (index)
+ return %0 : index
+}
+
+// -----
+
+// CHECK-LABEL: emitc.func @index_args_only(%arg0: !emitc.size_t) -> f32
+func.func @index_args_only(%i: index) -> f32 {
+ %0 = arith.constant 0.0 : f32
+ return %0 : f32
+}
diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir
index f5ef821cc9c05..26e1286e87ead 100644
--- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir
+++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir
@@ -52,3 +52,25 @@ module @globals {
return
}
}
+
+// -----
+
+// CHECK-LABEL: memref_index_values
+// CHECK-SAME: %[[argi:.*]]: index, %[[argj:.*]]: index
+// CHECK-SAME: -> index
+func.func @memref_index_values(%i: index, %j: index) -> index {
+ // CHECK: %[[i:.*]] = builtin.unrealized_conversion_cast %[[argi]] : index to !emitc.size_t
+ // CHECK: %[[j:.*]] = builtin.unrealized_conversion_cast %[[argj]] : index to !emitc.size_t
+
+ // CHECK: %[[ALLOCA:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.array<4x8x!emitc.size_t>
+ %0 = memref.alloca() : memref<4x8xindex>
+
+ // CHECK: %[[LOAD:.*]] = emitc.subscript %[[ALLOCA]][%[[i]], %[[j]]] : (!emitc.array<4x8x!emitc.size_t>, !emitc.size_t, !emitc.size_t) -> !emitc.size_t
+ // CHECK: %[[VAR:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.size_t
+ // CHECK: emitc.assign %[[LOAD]] : !emitc.size_t to %[[VAR]] : !emitc.size_t
+ %1 = memref.load %0[%i, %j] : memref<4x8xindex>
+
+ // CHECK: %[[CAST_RET:.*]] = builtin.unrealized_conversion_cast %[[VAR]] : !emitc.size_t to index
+ // CHECK: return %[[CAST_RET]] : index
+ return %1 : index
+}
diff --git a/mlir/test/Conversion/SCFToEmitC/nest-for-if.mlir b/mlir/test/Conversion/SCFToEmitC/nest-for-if.mlir
new file mode 100644
index 0000000000000..572ec657483ab
--- /dev/null
+++ b/mlir/test/Conversion/SCFToEmitC/nest-for-if.mlir
@@ -0,0 +1,33 @@
+// RUN: mlir-opt -allow-unregistered-dialect -convert-scf-to-emitc %s | FileCheck %s
+
+// CHECK-LABEL: func.func @nest_for_in_if
+// CHECK-SAME: %[[ARG_0:.*]]: i1, %[[ARG_1:.*]]: index, %[[ARG_2:.*]]: index, %[[ARG_3:.*]]: index, %[[ARG_4:.*]]: f32
+// CHECK-NEXT: %[[CAST_0:.*]] = builtin.unrealized_conversion_cast %[[ARG_1]] : index to !emitc.size_t
+// CHECK-NEXT: %[[CAST_1:.*]] = builtin.unrealized_conversion_cast %[[ARG_2]] : index to !emitc.size_t
+// CHECK-NEXT: %[[CAST_2:.*]] = builtin.unrealized_conversion_cast %[[ARG_3]] : index to !emitc.size_t
+// CHECK-NEXT: emitc.if %[[ARG_0]] {
+// CHECK-NEXT: emitc.for %[[ARG_5:.*]] = %[[CAST_0]] to %[[CAST_1]] step %[[CAST_2]] {
+// CHECK-NEXT: %[[CST_1:.*]] = arith.constant 1 : index
+// CHECK-NEXT: %[[CAST_3:.*]] = builtin.unrealized_conversion_cast %[[CST_1]] : index to !emitc.size_t
+// CHECK-NEXT: emitc.for %[[ARG_6:.*]] = %[[CAST_0]] to %[[CAST_1]] step %[[CAST_3]] {
+// CHECK-NEXT: %[[CST_2:.*]] = arith.constant 1 : index
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+// CHECK-NEXT: } else {
+// CHECK-NEXT: %3 = emitc.call_opaque "func_false"(%[[ARG_4]]) : (f32) -> i32
+// CHECK-NEXT: }
+// CHECK-NEXT: return
+// CHECK-NEXT: }
+func.func @nest_for_in_if(%arg0: i1, %arg1: index, %arg2: index, %arg3: index, %arg4: f32) {
+ scf.if %arg0 {
+ scf.for %i0 = %arg1 to %arg2 step %arg3 {
+ %c1 = arith.constant 1 : index
+ scf.for %i1 = %arg1 to %arg2 step %c1 {
+ %c1_0 = arith.constant 1 : index
+ }
+ }
+ } else {
+ %0 = emitc.call_opaque "func_false"(%arg4) : (f32) -> i32
+ }
+ return
+}
>From b44fe89008ac12b51e65b82af02bc6a0855f7e83 Mon Sep 17 00:00:00 2001
From: Matthias Gehre <matthias.gehre at amd.com>
Date: Wed, 10 Jul 2024 15:57:34 +0200
Subject: [PATCH 2/5] Merge pull request #213 from Xilinx/matthias.emitc_func
[mlir][EmitC] Fix call ops with zero arguments in func to emitc conversion (llvm#94936)
---
mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp | 13 +++++--------
.../Conversion/FuncToEmitC/func-to-emitc.mlir | 16 ++++++++++++++++
2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
index f2ea9add77d87..8dbf15e4174d3 100644
--- a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
+++ b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
@@ -37,16 +37,13 @@ class CallOpConversion final : public OpConversionPattern<func::CallOp> {
callOp, "only functions with zero or one result can be converted");
// Convert the original function results.
- Type resultTy = nullptr;
- if (callOp.getNumResults()) {
- resultTy = typeConverter->convertType(callOp.getResult(0).getType());
- if (!resultTy)
- return rewriter.notifyMatchFailure(
- callOp, "function return type conversion failed");
+ SmallVector<Type> types;
+ if (failed(typeConverter->convertTypes(callOp.getResultTypes(), types))) {
+ return rewriter.notifyMatchFailure(
+ callOp, "function return type conversion failed");
}
-
rewriter.replaceOpWithNewOp<emitc::CallOp>(
- callOp, resultTy, adaptor.getOperands(), callOp->getAttrs());
+ callOp, types, adaptor.getOperands(), callOp->getAttrs());
return success();
}
diff --git a/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir b/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
index 046073eb30306..611ac44e8ad1e 100644
--- a/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
+++ b/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
@@ -104,3 +104,19 @@ func.func @index_args_only(%i: index) -> f32 {
%0 = arith.constant 0.0 : f32
return %0 : f32
}
+
+// -----
+
+// CHECK-LABEL: emitc.func private @return_void() attributes {specifiers = ["static"]}
+// CHECK-NEXT: emitc.return
+func.func private @return_void() {
+ return
+}
+
+// CHECK-LABEL: emitc.func @call()
+// CHECK-NEXT: emitc.call @return_void() : () -> ()
+// CHECK-NEXT: emitc.return
+func.func @call() {
+ call @return_void() : () -> ()
+ return
+}
>From 5b65859fa8adb828ff095c5520fe85f884ca0dbe Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Wed, 2 Apr 2025 08:51:55 -0600
Subject: [PATCH 3/5] Fix tests wrt upstream changes
---
.../Conversion/FuncToEmitC/func-to-emitc.mlir | 12 +++++-----
.../MemRefToEmitC/memref-to-emitc.mlir | 23 +++++++++++--------
.../Conversion/SCFToEmitC/nest-for-if.mlir | 10 ++++----
3 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir b/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
index 611ac44e8ad1e..241b0dad5755f 100644
--- a/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
+++ b/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
@@ -79,7 +79,7 @@ func.func @call() {
// CHECK-LABEL: emitc.func @use_index
// CHECK-SAME: (%[[Arg0:.*]]: !emitc.size_t) -> !emitc.size_t
-// CHECK: emitc.return %[[Arg0]] : !emitc.size_t
+// CHECK: return %[[Arg0]] : !emitc.size_t
func.func @use_index(%arg0: index) -> index {
return %arg0 : index
}
@@ -90,8 +90,8 @@ func.func @use_index(%arg0: index) -> index {
func.func private @prototype_index(%arg0: index) -> index
// CHECK-LABEL: emitc.func @call(%arg0: !emitc.size_t) -> !emitc.size_t
-// CHECK-NEXT: %0 = emitc.call @prototype_index(%arg0) : (!emitc.size_t) -> !emitc.size_t
-// CHECK-NEXT: emitc.return %0 : !emitc.size_t
+// CHECK-NEXT: %0 = call @prototype_index(%arg0) : (!emitc.size_t) -> !emitc.size_t
+// CHECK-NEXT: return %0 : !emitc.size_t
func.func @call(%arg0: index) -> index {
%0 = call @prototype_index(%arg0) : (index) -> (index)
return %0 : index
@@ -108,14 +108,14 @@ func.func @index_args_only(%i: index) -> f32 {
// -----
// CHECK-LABEL: emitc.func private @return_void() attributes {specifiers = ["static"]}
-// CHECK-NEXT: emitc.return
+// CHECK-NEXT: return
func.func private @return_void() {
return
}
// CHECK-LABEL: emitc.func @call()
-// CHECK-NEXT: emitc.call @return_void() : () -> ()
-// CHECK-NEXT: emitc.return
+// CHECK-NEXT: call @return_void() : () -> ()
+// CHECK-NEXT: return
func.func @call() {
call @return_void() : () -> ()
return
diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir
index 26e1286e87ead..738e2dd09bc38 100644
--- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir
+++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir
@@ -12,9 +12,11 @@ func.func @alloca() {
// CHECK-LABEL: memref_store
// CHECK-SAME: %[[buff:.*]]: memref<4x8xf32>, %[[v:.*]]: f32, %[[i:.*]]: index, %[[j:.*]]: index
func.func @memref_store(%buff : memref<4x8xf32>, %v : f32, %i: index, %j: index) {
- // CHECK-NEXT: %[[BUFFER:.*]] = builtin.unrealized_conversion_cast %[[buff]] : memref<4x8xf32> to !emitc.array<4x8xf32>
+ // CHECK-DAG: %[[IDX_I:.*]] = builtin.unrealized_conversion_cast %[[i]] : index to !emitc.size_t
+ // CHECK-DAG: %[[IDX_J:.*]] = builtin.unrealized_conversion_cast %[[j]] : index to !emitc.size_t
+ // CHECK-DAG: %[[BUFFER:.*]] = builtin.unrealized_conversion_cast %[[buff]] : memref<4x8xf32> to !emitc.array<4x8xf32>
- // CHECK-NEXT: %[[SUBSCRIPT:.*]] = emitc.subscript %[[BUFFER]][%[[i]], %[[j]]] : (!emitc.array<4x8xf32>, index, index) -> !emitc.lvalue<f32>
+ // CHECK-NEXT: %[[SUBSCRIPT:.*]] = emitc.subscript %[[BUFFER]][%[[IDX_I]], %[[IDX_J]]] : (!emitc.array<4x8xf32>, !emitc.size_t, !emitc.size_t) -> !emitc.lvalue<f32>
// CHECK-NEXT: emitc.assign %[[v]] : f32 to %[[SUBSCRIPT]] : <f32>
memref.store %v, %buff[%i, %j] : memref<4x8xf32>
return
@@ -25,9 +27,11 @@ func.func @memref_store(%buff : memref<4x8xf32>, %v : f32, %i: index, %j: index)
// CHECK-LABEL: memref_load
// CHECK-SAME: %[[buff:.*]]: memref<4x8xf32>, %[[i:.*]]: index, %[[j:.*]]: index
func.func @memref_load(%buff : memref<4x8xf32>, %i: index, %j: index) -> f32 {
- // CHECK-NEXT: %[[BUFFER:.*]] = builtin.unrealized_conversion_cast %[[buff]] : memref<4x8xf32> to !emitc.array<4x8xf32>
+ // CHECK-DAG: %[[IDX_I:.*]] = builtin.unrealized_conversion_cast %[[i]] : index to !emitc.size_t
+ // CHECK-DAG: %[[IDX_J:.*]] = builtin.unrealized_conversion_cast %[[j]] : index to !emitc.size_t
+ // CHECK-DAG: %[[BUFFER:.*]] = builtin.unrealized_conversion_cast %[[buff]] : memref<4x8xf32> to !emitc.array<4x8xf32>
- // CHECK-NEXT: %[[SUBSCRIPT:.*]] = emitc.subscript %[[BUFFER]][%[[i]], %[[j]]] : (!emitc.array<4x8xf32>, index, index) -> !emitc.lvalue<f32>
+ // CHECK-NEXT: %[[SUBSCRIPT:.*]] = emitc.subscript %[[BUFFER]][%[[IDX_I]], %[[IDX_J]]] : (!emitc.array<4x8xf32>, !emitc.size_t, !emitc.size_t) -> !emitc.lvalue<f32>
// CHECK-NEXT: %[[LOAD:.*]] = emitc.load %[[SUBSCRIPT]] : <f32>
%1 = memref.load %buff[%i, %j] : memref<4x8xf32>
// CHECK-NEXT: return %[[LOAD]] : f32
@@ -59,18 +63,17 @@ module @globals {
// CHECK-SAME: %[[argi:.*]]: index, %[[argj:.*]]: index
// CHECK-SAME: -> index
func.func @memref_index_values(%i: index, %j: index) -> index {
- // CHECK: %[[i:.*]] = builtin.unrealized_conversion_cast %[[argi]] : index to !emitc.size_t
- // CHECK: %[[j:.*]] = builtin.unrealized_conversion_cast %[[argj]] : index to !emitc.size_t
+ // CHECK-DAG: %[[i:.*]] = builtin.unrealized_conversion_cast %[[argi]] : index to !emitc.size_t
+ // CHECK-DAG: %[[j:.*]] = builtin.unrealized_conversion_cast %[[argj]] : index to !emitc.size_t
// CHECK: %[[ALLOCA:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.array<4x8x!emitc.size_t>
%0 = memref.alloca() : memref<4x8xindex>
- // CHECK: %[[LOAD:.*]] = emitc.subscript %[[ALLOCA]][%[[i]], %[[j]]] : (!emitc.array<4x8x!emitc.size_t>, !emitc.size_t, !emitc.size_t) -> !emitc.size_t
- // CHECK: %[[VAR:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.size_t
- // CHECK: emitc.assign %[[LOAD]] : !emitc.size_t to %[[VAR]] : !emitc.size_t
+ // CHECK: %[[SUBSCRIPT:.*]] = emitc.subscript %[[ALLOCA]][%[[i]], %[[j]]] : (!emitc.array<4x8x!emitc.size_t>, !emitc.size_t, !emitc.size_t) -> !emitc.lvalue<!emitc.size_t>
+ // CHECK: %[[LOAD:.*]] = emitc.load %[[SUBSCRIPT]] : <!emitc.size_t>
%1 = memref.load %0[%i, %j] : memref<4x8xindex>
- // CHECK: %[[CAST_RET:.*]] = builtin.unrealized_conversion_cast %[[VAR]] : !emitc.size_t to index
+ // CHECK: %[[CAST_RET:.*]] = builtin.unrealized_conversion_cast %[[LOAD]] : !emitc.size_t to index
// CHECK: return %[[CAST_RET]] : index
return %1 : index
}
diff --git a/mlir/test/Conversion/SCFToEmitC/nest-for-if.mlir b/mlir/test/Conversion/SCFToEmitC/nest-for-if.mlir
index 572ec657483ab..bd3aa8acfcc0e 100644
--- a/mlir/test/Conversion/SCFToEmitC/nest-for-if.mlir
+++ b/mlir/test/Conversion/SCFToEmitC/nest-for-if.mlir
@@ -2,19 +2,19 @@
// CHECK-LABEL: func.func @nest_for_in_if
// CHECK-SAME: %[[ARG_0:.*]]: i1, %[[ARG_1:.*]]: index, %[[ARG_2:.*]]: index, %[[ARG_3:.*]]: index, %[[ARG_4:.*]]: f32
-// CHECK-NEXT: %[[CAST_0:.*]] = builtin.unrealized_conversion_cast %[[ARG_1]] : index to !emitc.size_t
-// CHECK-NEXT: %[[CAST_1:.*]] = builtin.unrealized_conversion_cast %[[ARG_2]] : index to !emitc.size_t
// CHECK-NEXT: %[[CAST_2:.*]] = builtin.unrealized_conversion_cast %[[ARG_3]] : index to !emitc.size_t
+// CHECK-NEXT: %[[CAST_1:.*]] = builtin.unrealized_conversion_cast %[[ARG_2]] : index to !emitc.size_t
+// CHECK-NEXT: %[[CAST_0:.*]] = builtin.unrealized_conversion_cast %[[ARG_1]] : index to !emitc.size_t
// CHECK-NEXT: emitc.if %[[ARG_0]] {
-// CHECK-NEXT: emitc.for %[[ARG_5:.*]] = %[[CAST_0]] to %[[CAST_1]] step %[[CAST_2]] {
+// CHECK-NEXT: for %[[ARG_5:.*]] = %[[CAST_0]] to %[[CAST_1]] step %[[CAST_2]] : !emitc.size_t {
// CHECK-NEXT: %[[CST_1:.*]] = arith.constant 1 : index
// CHECK-NEXT: %[[CAST_3:.*]] = builtin.unrealized_conversion_cast %[[CST_1]] : index to !emitc.size_t
-// CHECK-NEXT: emitc.for %[[ARG_6:.*]] = %[[CAST_0]] to %[[CAST_1]] step %[[CAST_3]] {
+// CHECK-NEXT: for %[[ARG_6:.*]] = %[[CAST_0]] to %[[CAST_1]] step %[[CAST_3]] : !emitc.size_t {
// CHECK-NEXT: %[[CST_2:.*]] = arith.constant 1 : index
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } else {
-// CHECK-NEXT: %3 = emitc.call_opaque "func_false"(%[[ARG_4]]) : (f32) -> i32
+// CHECK-NEXT: %3 = call_opaque "func_false"(%[[ARG_4]]) : (f32) -> i32
// CHECK-NEXT: }
// CHECK-NEXT: return
// CHECK-NEXT: }
>From 589065920f3f3673470b62a3405e42c0a8ec7b6d Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Wed, 2 Apr 2025 09:00:07 -0600
Subject: [PATCH 4/5] Remove duplicate test
---
.../Conversion/FuncToEmitC/func-to-emitc.mlir | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir b/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
index 241b0dad5755f..4c151a244d2d0 100644
--- a/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
+++ b/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
@@ -104,19 +104,3 @@ func.func @index_args_only(%i: index) -> f32 {
%0 = arith.constant 0.0 : f32
return %0 : f32
}
-
-// -----
-
-// CHECK-LABEL: emitc.func private @return_void() attributes {specifiers = ["static"]}
-// CHECK-NEXT: return
-func.func private @return_void() {
- return
-}
-
-// CHECK-LABEL: emitc.func @call()
-// CHECK-NEXT: call @return_void() : () -> ()
-// CHECK-NEXT: return
-func.func @call() {
- call @return_void() : () -> ()
- return
-}
>From 3f85d554e92eaba474dad76db3cea50c3a448156 Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Wed, 2 Apr 2025 09:12:18 -0600
Subject: [PATCH 5/5] Test not part of the PR
---
.../Conversion/SCFToEmitC/nest-for-if.mlir | 33 -------------------
1 file changed, 33 deletions(-)
delete mode 100644 mlir/test/Conversion/SCFToEmitC/nest-for-if.mlir
diff --git a/mlir/test/Conversion/SCFToEmitC/nest-for-if.mlir b/mlir/test/Conversion/SCFToEmitC/nest-for-if.mlir
deleted file mode 100644
index bd3aa8acfcc0e..0000000000000
--- a/mlir/test/Conversion/SCFToEmitC/nest-for-if.mlir
+++ /dev/null
@@ -1,33 +0,0 @@
-// RUN: mlir-opt -allow-unregistered-dialect -convert-scf-to-emitc %s | FileCheck %s
-
-// CHECK-LABEL: func.func @nest_for_in_if
-// CHECK-SAME: %[[ARG_0:.*]]: i1, %[[ARG_1:.*]]: index, %[[ARG_2:.*]]: index, %[[ARG_3:.*]]: index, %[[ARG_4:.*]]: f32
-// CHECK-NEXT: %[[CAST_2:.*]] = builtin.unrealized_conversion_cast %[[ARG_3]] : index to !emitc.size_t
-// CHECK-NEXT: %[[CAST_1:.*]] = builtin.unrealized_conversion_cast %[[ARG_2]] : index to !emitc.size_t
-// CHECK-NEXT: %[[CAST_0:.*]] = builtin.unrealized_conversion_cast %[[ARG_1]] : index to !emitc.size_t
-// CHECK-NEXT: emitc.if %[[ARG_0]] {
-// CHECK-NEXT: for %[[ARG_5:.*]] = %[[CAST_0]] to %[[CAST_1]] step %[[CAST_2]] : !emitc.size_t {
-// CHECK-NEXT: %[[CST_1:.*]] = arith.constant 1 : index
-// CHECK-NEXT: %[[CAST_3:.*]] = builtin.unrealized_conversion_cast %[[CST_1]] : index to !emitc.size_t
-// CHECK-NEXT: for %[[ARG_6:.*]] = %[[CAST_0]] to %[[CAST_1]] step %[[CAST_3]] : !emitc.size_t {
-// CHECK-NEXT: %[[CST_2:.*]] = arith.constant 1 : index
-// CHECK-NEXT: }
-// CHECK-NEXT: }
-// CHECK-NEXT: } else {
-// CHECK-NEXT: %3 = call_opaque "func_false"(%[[ARG_4]]) : (f32) -> i32
-// CHECK-NEXT: }
-// CHECK-NEXT: return
-// CHECK-NEXT: }
-func.func @nest_for_in_if(%arg0: i1, %arg1: index, %arg2: index, %arg3: index, %arg4: f32) {
- scf.if %arg0 {
- scf.for %i0 = %arg1 to %arg2 step %arg3 {
- %c1 = arith.constant 1 : index
- scf.for %i1 = %arg1 to %arg2 step %c1 {
- %c1_0 = arith.constant 1 : index
- }
- }
- } else {
- %0 = emitc.call_opaque "func_false"(%arg4) : (f32) -> i32
- }
- return
-}
More information about the Mlir-commits
mailing list