From 595a273d9232a7378c583fb109212370d6d2f4e4 Mon Sep 17 00:00:00 2001 From: Andrey Timonin Date: Mon, 16 Jun 2025 19:37:39 +0500 Subject: [PATCH] [mlir][emitc] Support 'emitc::LValueType' in 'emitc::VerbatimOp' (#144151) This PR introduces support for `emitc::LvalueType` in `emitc::VerbatimOp`, providing a mechanism to reduce the number of operations required when working with verbatim operations whose arguments are of type `emitc::LvalueType`. Before: ```mlir emitc.func @foo() { %a = "emitc.variable"() <{value = #emitc.opaque<"1">}> : () -> !emitc.lvalue %loaded_a = load %a : !emitc.lvalue emitc.verbatim "{} + {};" args %loaded_a, %loaded_a : i32, i32 return } ``` After: ```mlir emitc.func @bar() { %a = "emitc.variable"() <{value = #emitc.opaque<"1">}> : () -> !emitc.lvalue emitc.verbatim "{} + {};" args %a, %a : !emitc.lvalue, !emitc.lvalue return } ``` You can now write something like this: ```mlir emitc.func @baz() { %a = "emitc.variable"() <{value = #emitc.opaque<"1">}> : () -> !emitc.lvalue emitc.verbatim "++{};" args %a : !emitc.lvalue return } ``` --- mlir/include/mlir/Dialect/EmitC/IR/EmitC.td | 2 +- mlir/test/Dialect/EmitC/ops.mlir | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td index d4aea52a0d48..e53d3e45875d 100644 --- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td +++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td @@ -1304,7 +1304,7 @@ def EmitC_VerbatimOp : EmitC_Op<"verbatim"> { FailureOr> parseFormatString(); }]; - let arguments = (ins StrAttr:$value, Variadic:$fmtArgs); + let arguments = (ins StrAttr:$value, Variadic>:$fmtArgs); let builders = [OpBuilder<(ins "::mlir::StringAttr":$value), [{ build($_builder, $_state, value, {}); }]>]; diff --git a/mlir/test/Dialect/EmitC/ops.mlir b/mlir/test/Dialect/EmitC/ops.mlir index 36d12e763afc..ad40313f95df 100644 --- a/mlir/test/Dialect/EmitC/ops.mlir +++ b/mlir/test/Dialect/EmitC/ops.mlir @@ -246,12 +246,20 @@ emitc.verbatim "typedef float f32;" // The value is not interpreted as format string if there are no operands. emitc.verbatim "{} { }" -func.func @test_verbatim(%arg0 : !emitc.ptr, %arg1 : i32) { +func.func @test_verbatim(%arg0 : !emitc.ptr, %arg1 : i32, %arg2: !emitc.array<3x!emitc.ptr>) { + %a = "emitc.variable"() <{value = #emitc.opaque<"1">}> : () -> !emitc.lvalue + + // Check that the lvalue type can be used by verbatim. + emitc.verbatim "++{};" args %a : !emitc.lvalue + + // Check that the array type can be used by verbatim. + emitc.verbatim "*{}[0] = 1;" args %arg2 : !emitc.array<3x!emitc.ptr> + emitc.verbatim "{} + {};" args %arg0, %arg1 : !emitc.ptr, i32 - // Check there is no ambiguity whether %a is the argument to the emitc.verbatim op. - emitc.verbatim "a" - %a = "emitc.constant"(){value = 42 : i32} : () -> i32 + // Check there is no ambiguity whether %b is the argument to the emitc.verbatim op. + emitc.verbatim "b" + %b = "emitc.constant"(){value = 42 : i32} : () -> i32 return }