diff --git a/mlir/lib/Dialect/SCF/IR/SCF.cpp b/mlir/lib/Dialect/SCF/IR/SCF.cpp index c75528a76c999..edb7299410370 100644 --- a/mlir/lib/Dialect/SCF/IR/SCF.cpp +++ b/mlir/lib/Dialect/SCF/IR/SCF.cpp @@ -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(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) { diff --git a/mlir/test/Dialect/SCF/invalid.mlir b/mlir/test/Dialect/SCF/invalid.mlir index 3f481ad5dbba7..6db43ffd4b81b 100644 --- a/mlir/test/Dialect/SCF/invalid.mlir +++ b/mlir/test/Dialect/SCF/invalid.mlir @@ -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) {