[MLIR][SCF] Verify number of regions in scf.reduce (#171450)

This patch adds `ReduceOp::verifyRegions` to ensure that the number of
reduction regions equals the number of operands (`getReductions().size()
== getOperands().size()`).

Additionally, `ParallelOp::verify` is updated to gracefully handle cases
where the number of reduce operands differs from the initial values,
preventing verification logic crashes and relying on `ReduceOp` to
report structural inconsistencies.

Fixes: #118768
This commit is contained in:
Men-cotton
2025-12-11 20:39:39 +09:00
committed by GitHub
parent 9b6b52b534
commit 06aecdbebe
2 changed files with 39 additions and 0 deletions

View File

@@ -3152,6 +3152,9 @@ LogicalResult ParallelOp::verify() {
return emitOpError() << "expects number of results: " << resultsSize
<< " to be the same as number of initial values: "
<< initValsSize;
if (reduceOp.getNumOperands() != initValsSize)
// Delegate error reporting to ReduceOp
return success();
// Check that the types of the results and reductions are the same.
for (int64_t i = 0; i < static_cast<int64_t>(reductionsSize); ++i) {
@@ -3454,6 +3457,11 @@ void ReduceOp::build(OpBuilder &builder, OperationState &result,
}
LogicalResult ReduceOp::verifyRegions() {
if (getReductions().size() != getOperands().size())
return emitOpError() << "expects number of reduction regions: "
<< getReductions().size()
<< " to be the same as number of reduction operands: "
<< getOperands().size();
// The region of a ReduceOp has two arguments of the same type as its
// corresponding operand.
for (int64_t i = 0, e = getReductions().size(); i < e; ++i) {

View File

@@ -274,6 +274,37 @@ func.func @parallel_different_types_of_results_and_reduces(
// -----
// The scf.parallel operation requires the number of operands in the terminator
// (scf.reduce) to match the number of initial values provided to the loop.
func.func @invalid_reduce_too_few_regions() {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
scf.parallel (%arg1) = (%c0) to (%c1) step (%c1) {
// expected-error @+1 {{expects number of reduction regions: 0 to be the same as number of reduction operands: 1}}
scf.reduce(%c1 : index)
}
return
}
// -----
// The scf.parallel operation requires the number of operands in the terminator
// (scf.reduce) to match the number of initial values provided to the loop.
func.func @invalid_reduce_too_many_regions() {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%0 = scf.parallel (%i0) = (%c0) to (%c1) step (%c1) init (%c0) -> (index) {
// expected-error @+1 {{expects number of reduction regions: 1 to be the same as number of reduction operands: 0}}
scf.reduce {
^bb0(%lhs : index, %rhs : index):
scf.reduce.return %lhs : index
}
}
return
}
// -----
func.func @top_level_reduce(%arg0 : f32) {
// expected-error@+1 {{expects parent op 'scf.parallel'}}
scf.reduce(%arg0 : f32) {