https://github.com/victor-eds updated https://github.com/llvm/llvm-project/pull/228746
>From 6704a6ae3d5ccf475d99dd4ddc273fa0b8beaba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20P=C3=A9rez=20Carrasco?= <[email protected]> Date: Fri, 2 Oct 2026 14:24:44 -0700 Subject: [PATCH] [mlir] Diagnose a single-result fold on an op without OneResult MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `getFoldHookFn` selects the single-result `OpFoldResult fold(...)` form only if the op has the OneResult trait. On an op without this trait, the dispatch ignores such a fold without a diagnostic. ODS declares this form only for an op with exactly one fixed result. So only a hand-written declaration can cause the problem: a `fold` in `extraClassDeclaration`, or an op class written in C++. No in-tree op does this. Add a `static_assert` that rejects a single-result fold on an op without the OneResult trait. No lit test can check a compile error. A scratch test op shows the bug: it has two results and a single-result fold that prints a line and returns its operand. Without this patch, the op compiles, and canonicalize never calls the fold: $ mlir-opt two_results_single_fold.mlir -canonicalize module { func.func @two_results_single_fold(%arg0: i32) -> (i32, i32) { %0:2 = "test.op_two_results_single_fold"(%arg0) : (i32) -> (i32, i32) return %0#0, %0#1 : i32, i32 } } With this patch, the test op does not compile: mlir/include/mlir/IR/OpDefinition.h:1905:19: error: static assertion failed due to requirement 'hasOneResult || !hasSingleResultFold': a single-result `OpFoldResult fold(...)` requires the OneResult trait; ops with zero, several, or variadic results must use `LogicalResult fold(FoldAdaptor, SmallVectorImpl<OpFoldResult> &)` Downstream impact: - An op without the OneResult trait that defines a single-result `fold` no longer compiles. If the op has exactly one result, it must add the OneResult trait. Otherwise it must use the multi-result form `LogicalResult fold(FoldAdaptor, SmallVectorImpl<OpFoldResult> &)`. Signed-off-by: Víctor Pérez Carrasco <[email protected]> --- mlir/include/mlir/IR/OpDefinition.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/mlir/include/mlir/IR/OpDefinition.h b/mlir/include/mlir/IR/OpDefinition.h index cb35ba7c8eaa2..783cd1359e970 100644 --- a/mlir/include/mlir/IR/OpDefinition.h +++ b/mlir/include/mlir/IR/OpDefinition.h @@ -1897,11 +1897,18 @@ class Op : public OpState, public Traits<ConcreteType>... { /// Return the internal implementations of each of the OperationName hooks. static constexpr FoldHookFn getFoldHookFn() { + constexpr bool hasOneResult = hasTrait<OpTrait::OneResult>(); + constexpr bool hasSingleResultFold = + has_single_result_fold_v<ConcreteType> || + has_fold_adaptor_single_result_v<ConcreteType>; + // Without this check, the dispatch below silently skips such a `fold`. + static_assert(hasOneResult || !hasSingleResultFold, + "a single-result `OpFoldResult fold(...)` requires the " + "OneResult trait; ops with zero, several, or variadic " + "results must use `LogicalResult fold(FoldAdaptor, " + "SmallVectorImpl<OpFoldResult> &)`"); // If the operation is single result and defines a `fold` method. - if constexpr (llvm::is_one_of<OpTrait::OneResult<ConcreteType>, - Traits<ConcreteType>...>::value && - (has_single_result_fold_v<ConcreteType> || - has_fold_adaptor_single_result_v<ConcreteType>)) + if constexpr (hasOneResult && hasSingleResultFold) return [](Operation *op, ArrayRef<Attribute> operands, SmallVectorImpl<OpFoldResult> &results) { return foldSingleResultHook<ConcreteType>(op, operands, results); _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
