[Mlir-commits] [mlir] 5e28271 - [MLIR][Func] Enable strict property assembly format (#217300)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Sep 8 16:47:02 PDT 2026
Author: Mehdi Amini
Date: 2026-09-08T23:46:56Z
New Revision: 5e282718a88c5e19dfe3524dee0bc91a5fa1e224
URL: https://github.com/llvm/llvm-project/commit/5e282718a88c5e19dfe3524dee0bc91a5fa1e224
DIFF: https://github.com/llvm/llvm-project/commit/5e282718a88c5e19dfe3524dee0bc91a5fa1e224.diff
LOG: [MLIR][Func] Enable strict property assembly format (#217300)
Enable the strict properties assembly format mode for the Func dialect.
Spell inherent call attributes directly in the call formats so they are
no longer parsed from attr-dict in strict mode.
Assisted-by: Codex
Added:
Modified:
mlir/include/mlir/Dialect/Func/IR/FuncOps.td
mlir/lib/Dialect/Func/IR/FuncOps.cpp
mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize.mlir
mlir/test/IR/core-ops.mlir
mlir/test/Transforms/canonicalize.mlir
mlir/test/Transforms/inlining.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/Func/IR/FuncOps.td b/mlir/include/mlir/Dialect/Func/IR/FuncOps.td
index 7d984092f5e33..d7a0d5fc4f277 100644
--- a/mlir/include/mlir/Dialect/Func/IR/FuncOps.td
+++ b/mlir/include/mlir/Dialect/Func/IR/FuncOps.td
@@ -22,6 +22,7 @@ def Func_Dialect : Dialect {
let name = "func";
let cppNamespace = "::mlir::func";
let hasConstantMaterializer = 1;
+ let useStrictPropertiesInAssemblyFormat = 1;
}
// Base class for Func dialect ops.
@@ -120,7 +121,8 @@ def CallOp : Func_Op<"call",
}];
let assemblyFormat = [{
- $callee `(` $operands `)` attr-dict `:` functional-type($operands, results)
+ $callee `(` $operands `)` prop-dict attr-dict `:`
+ functional-type($operands, results)
}];
}
@@ -197,7 +199,12 @@ def CallIndirectOp : Func_Op<"call_indirect", [
let hasCanonicalizeMethod = 1;
let assemblyFormat = [{
- $callee `(` $callee_operands `)` attr-dict `:` type($callee)
+ $callee `(` $callee_operands `)`
+ oilist<`,`>(
+ `arg_attrs` `=` $arg_attrs
+ | `res_attrs` `=` $res_attrs
+ )
+ attr-dict `:` type($callee)
}];
}
diff --git a/mlir/lib/Dialect/Func/IR/FuncOps.cpp b/mlir/lib/Dialect/Func/IR/FuncOps.cpp
index be31234f98d1f..6c41eeb36e9cb 100644
--- a/mlir/lib/Dialect/Func/IR/FuncOps.cpp
+++ b/mlir/lib/Dialect/Func/IR/FuncOps.cpp
@@ -86,14 +86,17 @@ FunctionType CallOp::getCalleeType() {
LogicalResult CallIndirectOp::canonicalize(CallIndirectOp indirectCall,
PatternRewriter &rewriter) {
// Check that the callee is a constant callee.
- SymbolRefAttr calledFn;
+ FlatSymbolRefAttr calledFn;
if (!matchPattern(indirectCall.getCallee(), m_Constant(&calledFn)))
return failure();
- // Replace with a direct call.
- rewriter.replaceOpWithNewOp<CallOp>(indirectCall, calledFn,
- indirectCall.getResultTypes(),
- indirectCall.getArgOperands());
+ // Replace with a direct call, preserving the call-site attributes.
+ auto directCall = CallOp::create(
+ rewriter, indirectCall.getLoc(), indirectCall.getResultTypes(), calledFn,
+ indirectCall.getArgOperands(), indirectCall.getArgAttrsAttr(),
+ indirectCall.getResAttrsAttr());
+ directCall->setDiscardableAttrs(indirectCall->getDiscardableAttrDictionary());
+ rewriter.replaceOp(indirectCall, directCall.getResults());
return success();
}
diff --git a/mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize.mlir b/mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize.mlir
index d20f06fd3278a..dbe44cba4d98f 100644
--- a/mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize.mlir
+++ b/mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize.mlir
@@ -599,8 +599,8 @@ func.func @equivalent_func_arg(%t0: tensor<?xf32> {bufferization.writable = true
// CHECK: scf.for {{.*}} iter_args(%[[t1:.*]] = %[[arg0]])
%1 = scf.for %iv = %c0 to %c10 step %c1 iter_args(%t1 = %t0) -> (tensor<?xf32>) {
// CHECK: call @inner_func(%[[t1]])
- // INHERENT: call @inner_func({{.*}}) {no_inline}
- %3 = func.call @inner_func(%t1) {no_inline} : (tensor<?xf32>) -> tensor<?xf32>
+ // INHERENT: call @inner_func({{.*}}) <no_inline>
+ %3 = func.call @inner_func(%t1) <no_inline> : (tensor<?xf32>) -> tensor<?xf32>
// CHECK: scf.yield %[[t1]]
scf.yield %3 : tensor<?xf32>
}
diff --git a/mlir/test/IR/core-ops.mlir b/mlir/test/IR/core-ops.mlir
index 5d1583111541c..0ab6775068a51 100644
--- a/mlir/test/IR/core-ops.mlir
+++ b/mlir/test/IR/core-ops.mlir
@@ -201,6 +201,25 @@ func.func @calls(%arg0: i32) {
// CHECK: %4 = call_indirect %f_0(%arg0) : (i32) -> i32
%3 = "func.call_indirect"(%f_0, %arg0) : ((i32) -> i32, i32) -> i32
+ // CHECK: %{{.*}} = call @return_op(%arg0) <arg_attrs = [{test.arg}],
+ // CHECK-SAME: res_attrs = [{test.res = 42 : i64}], no_inline> : (i32) -> i32
+ %4 = call @return_op(%arg0) <arg_attrs = [{test.arg}],
+ res_attrs = [{test.res = 42 : i64}], no_inline> : (i32) -> i32
+
+ // CHECK: %{{.*}} = call_indirect %f_0(%arg0)
+ // CHECK-SAME: arg_attrs = [{test.arg}],
+ // CHECK-SAME: res_attrs = [{test.res = 42 : i64}] : (i32) -> i32
+ %5 = call_indirect %f_0(%arg0) res_attrs = [{test.res = 42 : i64}],
+ arg_attrs = [{test.arg}] : (i32) -> i32
+
+ // CHECK: call @affine_apply() <arg_attrs = [], res_attrs = []>
+ // CHECK-SAME: {test.marker} : () -> ()
+ call @affine_apply() <arg_attrs = [], res_attrs = []> {test.marker} : () -> ()
+
+ // CHECK: call_indirect %f() arg_attrs = [], res_attrs = []
+ // CHECK-SAME: {test.marker} : () -> ()
+ call_indirect %f() arg_attrs = [], res_attrs = [] {test.marker} : () -> ()
+
return
}
diff --git a/mlir/test/Transforms/canonicalize.mlir b/mlir/test/Transforms/canonicalize.mlir
index 8e02c06a0a293..8337cccbb7538 100644
--- a/mlir/test/Transforms/canonicalize.mlir
+++ b/mlir/test/Transforms/canonicalize.mlir
@@ -587,6 +587,22 @@ func.func @indirect_call_folding() {
return
}
+func.func @attributed_indirect_target(%arg: i32) -> i32 {
+ return %arg : i32
+}
+
+// CHECK-LABEL: func @attributed_indirect_call_folding
+// CHECK-SAME: (%[[ARG:.*]]: i32)
+func.func @attributed_indirect_call_folding(%arg: i32) -> i32 {
+ // CHECK: %[[RESULT:.*]] = call @attributed_indirect_target(%[[ARG]])
+ // CHECK-SAME: <arg_attrs = [{test.arg}], res_attrs = [{test.res}]>
+ // CHECK-SAME: {test.discardable} : (i32) -> i32
+ %fn = constant @attributed_indirect_target : (i32) -> i32
+ %result = call_indirect %fn(%arg) arg_attrs = [{test.arg}],
+ res_attrs = [{test.res}] {test.discardable} : (i32) -> i32
+ return %result : i32
+}
+
//
// IMPORTANT NOTE: the operations in this test are exactly those produced by
// lowering affine.apply affine_map<(i) -> (i mod 42)> to standard operations. Please only
diff --git a/mlir/test/Transforms/inlining.mlir b/mlir/test/Transforms/inlining.mlir
index da3f1a28deaac..5b3b1d8cd211f 100644
--- a/mlir/test/Transforms/inlining.mlir
+++ b/mlir/test/Transforms/inlining.mlir
@@ -28,7 +28,7 @@ func.func @noinline_with_arg(%arg0 : i32) -> i32 {
// CHECK-NEXT: func_with_arg
// CHECK-NEXT: return
- %0 = call @func_with_arg(%arg0) {no_inline} : (i32) -> i32
+ %0 = call @func_with_arg(%arg0) <no_inline> : (i32) -> i32
return %0 : i32
}
More information about the Mlir-commits
mailing list