[Mlir-commits] [mlir] 00aa1a8 - Revert "[mlir][irdl] Support variadicity check in operations"
Mathieu Fehr
llvmlistbot at llvm.org
Sun Aug 20 07:58:26 PDT 2023
Author: Mathieu Fehr
Date: 2023-08-20T16:57:40+01:00
New Revision: 00aa1a8c3d0b8ca49e10dc2b9e54ac0b2d1149c3
URL: https://github.com/llvm/llvm-project/commit/00aa1a8c3d0b8ca49e10dc2b9e54ac0b2d1149c3
DIFF: https://github.com/llvm/llvm-project/commit/00aa1a8c3d0b8ca49e10dc2b9e54ac0b2d1149c3.diff
LOG: Revert "[mlir][irdl] Support variadicity check in operations"
This reverts commit 62b2b399924cc98c349979a84f1e375b97ee924c.
This is the error reported by the buildbot:
/home/buildbots/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/mlir/lib/Dialect/IRDL/IRDLLoading.cpp:97:22: error: no member named 'reduce' in namespace 'std'
int32_t sum = std::reduce(denseSegmentSizes.asArrayRef().begin(),
Full details are available at:
https://lab.llvm.org/buildbot#builders/21/builds/78689
Added:
Modified:
mlir/lib/Dialect/IRDL/IRDLLoading.cpp
mlir/test/Dialect/IRDL/variadics.irdl.mlir
Removed:
mlir/test/Dialect/IRDL/variadics.mlir
################################################################################
diff --git a/mlir/lib/Dialect/IRDL/IRDLLoading.cpp b/mlir/lib/Dialect/IRDL/IRDLLoading.cpp
index 1eef82b8116946..527596705ae8bf 100644
--- a/mlir/lib/Dialect/IRDL/IRDLLoading.cpp
+++ b/mlir/lib/Dialect/IRDL/IRDLLoading.cpp
@@ -21,7 +21,6 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/SMLoc.h"
-#include <numeric>
using namespace mlir;
using namespace mlir::irdl;
@@ -50,161 +49,26 @@ irdlAttrOrTypeVerifier(function_ref<InFlightDiagnostic()> emitError,
return success();
}
-/// Get the operand segment sizes from the attribute dictionary.
-LogicalResult getSegmentSizesFromAttr(Operation *op, StringRef elemName,
- StringRef attrName, unsigned numElements,
- ArrayRef<Variadicity> variadicities,
- SmallVectorImpl<int> &segmentSizes) {
- // Get the segment sizes attribute, and check that it is of the right type.
- Attribute segmentSizesAttr = op->getAttr(attrName);
- if (!segmentSizesAttr) {
- return op->emitError() << "'" << attrName
- << "' attribute is expected but not provided";
- }
-
- auto denseSegmentSizes = dyn_cast<DenseI32ArrayAttr>(segmentSizesAttr);
- if (!denseSegmentSizes) {
- return op->emitError() << "'" << attrName
- << "' attribute is expected to be a dense i32 array";
- }
-
- if (denseSegmentSizes.size() != (int64_t)variadicities.size()) {
- return op->emitError() << "'" << attrName << "' attribute for specifying "
- << elemName << " segments must have "
- << variadicities.size() << " elements, but got "
- << denseSegmentSizes.size();
- }
-
- // Check that the segment sizes are corresponding to the given variadicities,
- for (auto [i, segmentSize, variadicity] :
- enumerate(denseSegmentSizes.asArrayRef(), variadicities)) {
- if (segmentSize < 0)
- return op->emitError()
- << "'" << attrName << "' attribute for specifying " << elemName
- << " segments must have non-negative values";
- if (variadicity == Variadicity::single && segmentSize != 1)
- return op->emitError() << "element " << i << " in '" << attrName
- << "' attribute must be equal to 1";
-
- if (variadicity == Variadicity::optional && segmentSize > 1)
- return op->emitError() << "element " << i << " in '" << attrName
- << "' attribute must be equal to 0 or 1";
-
- segmentSizes.push_back(segmentSize);
- }
-
- // Check that the sum of the segment sizes is equal to the number of elements.
- int32_t sum = std::reduce(denseSegmentSizes.asArrayRef().begin(),
- denseSegmentSizes.asArrayRef().end(), 0);
- if (sum != static_cast<int32_t>(numElements))
- return op->emitError() << "sum of elements in '" << attrName
- << "' attribute must be equal to the number of "
- << elemName << "s";
-
- return success();
-}
-
-/// Compute the segment sizes of the given element (operands, results).
-/// If the operation has more than two non-single elements (optional or
-/// variadic), then get the segment sizes from the attribute dictionary.
-/// Otherwise, compute the segment sizes from the number of elements.
-/// `elemName` should be either `"operand"` or `"result"`.
-LogicalResult getSegmentSizes(Operation *op, StringRef elemName,
- StringRef attrName, unsigned numElements,
- ArrayRef<Variadicity> variadicities,
- SmallVectorImpl<int> &segmentSizes) {
- // If we have more than one non-single variadicity, we need to get the
- // segment sizes from the attribute dictionary.
- int numberNonSingle = count_if(
- variadicities, [](Variadicity v) { return v != Variadicity::single; });
- if (numberNonSingle > 1)
- return getSegmentSizesFromAttr(op, elemName, attrName, numElements,
- variadicities, segmentSizes);
-
- // If we only have single variadicities, the segments sizes are all 1.
- if (numberNonSingle == 0) {
- if (numElements != variadicities.size()) {
- return op->emitError() << "op expects exactly " << variadicities.size()
- << " " << elemName << "s, but got " << numElements;
- }
- for (size_t i = 0, e = variadicities.size(); i < e; ++i)
- segmentSizes.push_back(1);
- return success();
- }
-
- assert(numberNonSingle == 1);
-
- // There is exactly one non-single element, so we can
- // compute its size and check that it is valid.
- int nonSingleSegmentSize = static_cast<int>(numElements) -
- static_cast<int>(variadicities.size()) + 1;
-
- if (nonSingleSegmentSize < 0) {
- return op->emitError() << "op expects at least " << variadicities.size() - 1
- << " " << elemName << "s, but got " << numElements;
- }
-
- // Add the segment sizes.
- for (Variadicity variadicity : variadicities) {
- if (variadicity == Variadicity::single) {
- segmentSizes.push_back(1);
- continue;
- }
-
- // If we have an optional element, we should check that it represents
- // zero or one elements.
- if (nonSingleSegmentSize > 1 && variadicity == Variadicity::optional)
- return op->emitError() << "op expects at most " << variadicities.size()
- << " " << elemName << "s, but got " << numElements;
-
- segmentSizes.push_back(nonSingleSegmentSize);
- }
-
- return success();
-}
-
-/// Compute the segment sizes of the given operands.
-/// If the operation has more than two non-single operands (optional or
-/// variadic), then get the segment sizes from the attribute dictionary.
-/// Otherwise, compute the segment sizes from the number of operands.
-LogicalResult getOperandSegmentSizes(Operation *op,
- ArrayRef<Variadicity> variadicities,
- SmallVectorImpl<int> &segmentSizes) {
- return getSegmentSizes(op, "operand", "operand_segment_sizes",
- op->getNumOperands(), variadicities, segmentSizes);
-}
-
-/// Compute the segment sizes of the given results.
-/// If the operation has more than two non-single results (optional or
-/// variadic), then get the segment sizes from the attribute dictionary.
-/// Otherwise, compute the segment sizes from the number of results.
-LogicalResult getResultSegmentSizes(Operation *op,
- ArrayRef<Variadicity> variadicities,
- SmallVectorImpl<int> &segmentSizes) {
- return getSegmentSizes(op, "result", "result_segment_sizes",
- op->getNumResults(), variadicities, segmentSizes);
-}
-
/// Verify that the given operation satisfies the given constraints.
/// This encodes the logic of the verification method for operations defined
/// with IRDL.
-static LogicalResult irdlOpVerifier(
- Operation *op, ArrayRef<std::unique_ptr<Constraint>> constraints,
- ArrayRef<size_t> operandConstrs, ArrayRef<Variadicity> operandVariadicity,
- ArrayRef<size_t> resultConstrs, ArrayRef<Variadicity> resultVariadicity,
- const DenseMap<StringAttr, size_t> &attributeConstrs) {
- // Get the segment sizes for the operands.
- // This will check that the number of operands is correct.
- SmallVector<int> operandSegmentSizes;
- if (failed(
- getOperandSegmentSizes(op, operandVariadicity, operandSegmentSizes)))
- return failure();
-
- // Get the segment sizes for the results.
- // This will check that the number of results is correct.
- SmallVector<int> resultSegmentSizes;
- if (failed(getResultSegmentSizes(op, resultVariadicity, resultSegmentSizes)))
- return failure();
+static LogicalResult
+irdlOpVerifier(Operation *op, ArrayRef<std::unique_ptr<Constraint>> constraints,
+ ArrayRef<size_t> operandConstrs, ArrayRef<size_t> resultConstrs,
+ const DenseMap<StringAttr, size_t> &attributeConstrs) {
+ /// Check that we have the right number of operands.
+ unsigned numOperands = op->getNumOperands();
+ size_t numExpectedOperands = operandConstrs.size();
+ if (numOperands != numExpectedOperands)
+ return op->emitOpError() << numExpectedOperands
+ << " operands expected, but got " << numOperands;
+
+ /// Check that we have the right number of results.
+ unsigned numResults = op->getNumResults();
+ size_t numExpectedResults = resultConstrs.size();
+ if (numResults != numExpectedResults)
+ return op->emitOpError()
+ << numExpectedResults << " results expected, but got " << numResults;
auto emitError = [op] { return op->emitError(); };
@@ -226,29 +90,17 @@ static LogicalResult irdlOpVerifier(
return failure();
}
- // Check that all operands satisfy the constraints
- int operandIdx = 0;
- for (auto [defIndex, segmentSize] : enumerate(operandSegmentSizes)) {
- for (int i = 0; i < segmentSize; i++) {
- if (failed(verifier.verify(
- {emitError}, TypeAttr::get(op->getOperandTypes()[operandIdx]),
- operandConstrs[defIndex])))
- return failure();
- ++operandIdx;
- }
- }
+ /// Check that all operands satisfy the constraints.
+ for (auto [i, operandType] : enumerate(op->getOperandTypes()))
+ if (failed(verifier.verify({emitError}, TypeAttr::get(operandType),
+ operandConstrs[i])))
+ return failure();
- // Check that all results satisfy the constraints
- int resultIdx = 0;
- for (auto [defIndex, segmentSize] : enumerate(resultSegmentSizes)) {
- for (int i = 0; i < segmentSize; i++) {
- if (failed(verifier.verify({emitError},
- TypeAttr::get(op->getResultTypes()[resultIdx]),
- resultConstrs[defIndex])))
- return failure();
- ++resultIdx;
- }
- }
+ /// Check that all results satisfy the constraints.
+ for (auto [i, resultType] : enumerate(op->getResultTypes()))
+ if (failed(verifier.verify({emitError}, TypeAttr::get(resultType),
+ resultConstrs[i])))
+ return failure();
return success();
}
@@ -283,7 +135,7 @@ static WalkResult loadOperation(
}
SmallVector<size_t> operandConstraints;
- SmallVector<Variadicity> operandVariadicity;
+ SmallVector<size_t> resultConstraints;
// Gather which constraint slots correspond to operand constraints
auto operandsOp = op.getOp<OperandsOp>();
@@ -297,15 +149,8 @@ static WalkResult loadOperation(
}
}
}
-
- // Gather the variadicities of each operand
- for (VariadicityAttr attr : operandsOp->getVariadicity())
- operandVariadicity.push_back(attr.getValue());
}
- SmallVector<size_t> resultConstraints;
- SmallVector<Variadicity> resultVariadicity;
-
// Gather which constraint slots correspond to result constraints
auto resultsOp = op.getOp<ResultsOp>();
if (resultsOp.has_value()) {
@@ -318,10 +163,6 @@ static WalkResult loadOperation(
}
}
}
-
- // Gather the variadicities of each result
- for (Attribute attr : resultsOp->getVariadicity())
- resultVariadicity.push_back(attr.cast<VariadicityAttr>().getValue());
}
// Gather which constraint slots correspond to attributes constraints
@@ -352,13 +193,10 @@ static WalkResult loadOperation(
auto verifier =
[constraints{std::move(constraints)},
operandConstraints{std::move(operandConstraints)},
- operandVariadicity{std::move(operandVariadicity)},
resultConstraints{std::move(resultConstraints)},
- resultVariadicity{std::move(resultVariadicity)},
attributesContraints{std::move(attributesContraints)}](Operation *op) {
return irdlOpVerifier(op, constraints, operandConstraints,
- operandVariadicity, resultConstraints,
- resultVariadicity, attributesContraints);
+ resultConstraints, attributesContraints);
};
// IRDL does not support defining regions.
diff --git a/mlir/test/Dialect/IRDL/variadics.irdl.mlir b/mlir/test/Dialect/IRDL/variadics.irdl.mlir
index 64c5e1878f08eb..6c051d0eaad487 100644
--- a/mlir/test/Dialect/IRDL/variadics.irdl.mlir
+++ b/mlir/test/Dialect/IRDL/variadics.irdl.mlir
@@ -29,13 +29,13 @@ irdl.dialect @testvar {
// CHECK-NEXT: %[[v0:[^ ]*]] = irdl.is i16
// CHECK-NEXT: %[[v1:[^ ]*]] = irdl.is i32
// CHECK-NEXT: %[[v2:[^ ]*]] = irdl.is i64
- // CHECK-NEXT: irdl.operands(%[[v0]], optional %[[v1]], %[[v2]])
+ // CHECK-NEXT: irdl.operands(%[[v0]], variadic %[[v1]], %[[v2]])
// CHECK-NEXT: }
irdl.operation @opt_operand {
%0 = irdl.is i16
%1 = irdl.is i32
%2 = irdl.is i64
- irdl.operands(%0, optional %1, %2)
+ irdl.operands(%0, variadic %1, %2)
}
// CHECK-LABEL: irdl.operation @var_and_opt_operand {
@@ -78,13 +78,13 @@ irdl.dialect @testvar {
// CHECK-NEXT: %[[v0:[^ ]*]] = irdl.is i16
// CHECK-NEXT: %[[v1:[^ ]*]] = irdl.is i32
// CHECK-NEXT: %[[v2:[^ ]*]] = irdl.is i64
- // CHECK-NEXT: irdl.results(%[[v0]], optional %[[v1]], %[[v2]])
+ // CHECK-NEXT: irdl.results(%[[v0]], variadic %[[v1]], %[[v2]])
// CHECK-NEXT: }
irdl.operation @opt_result {
%0 = irdl.is i16
%1 = irdl.is i32
%2 = irdl.is i64
- irdl.results(%0, optional %1, %2)
+ irdl.results(%0, variadic %1, %2)
}
// CHECK-LABEL: irdl.operation @var_and_opt_result {
diff --git a/mlir/test/Dialect/IRDL/variadics.mlir b/mlir/test/Dialect/IRDL/variadics.mlir
deleted file mode 100644
index a8871fcf5ebd9a..00000000000000
--- a/mlir/test/Dialect/IRDL/variadics.mlir
+++ /dev/null
@@ -1,400 +0,0 @@
-// RUN: mlir-opt %s --irdl-file=%S/variadics.irdl.mlir -split-input-file -verify-diagnostics | FileCheck %s
-
-//===----------------------------------------------------------------------===//
-// Single operand
-//===----------------------------------------------------------------------===//
-
-// Test an operation with a single operand.
-func.func @testSingleOperand(%x: i32) {
- "testvar.single_operand"(%x) : (i32) -> ()
- // CHECK: "testvar.single_operand"(%{{.*}}) : (i32) -> ()
- return
-}
-
-// -----
-
-// Test an operation with a single operand definition and a wrong number of operands.
-func.func @testSingleOperandFail(%x: i32) {
- // expected-error at +1 {{op expects exactly 1 operands, but got 2}}
- "testvar.single_operand"(%x, %x) : (i32, i32) -> ()
- return
-}
-
-// -----
-
-// Test an operation with a single operand definition and a wrong number of operands.
-func.func @testSingleOperandFail() {
- // expected-error at +1 {{op expects exactly 1 operands, but got 0}}
- "testvar.single_operand"() : () -> ()
- return
-}
-
-// -----
-
-
-//===----------------------------------------------------------------------===//
-// Variadic operand
-//===----------------------------------------------------------------------===//
-
-// Test an operation with a single variadic operand.
-func.func @testVarOperand(%x: i16, %y: i32, %z: i64) {
- "testvar.var_operand"(%x, %z) : (i16, i64) -> ()
- // CHECK: "testvar.var_operand"(%{{.*}}, %{{.*}}) : (i16, i64) -> ()
- "testvar.var_operand"(%x, %y, %z) : (i16, i32, i64) -> ()
- // CHECK-NEXT: "testvar.var_operand"(%{{.*}}, %{{.*}}, %{{.*}}) : (i16, i32, i64) -> ()
- "testvar.var_operand"(%x, %y, %y, %z) : (i16, i32, i32, i64) -> ()
- // CHECK-NEXT: "testvar.var_operand"(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) : (i16, i32, i32, i64) -> ()
- "testvar.var_operand"(%x, %y, %y, %y, %z) : (i16, i32, i32, i32, i64) -> ()
- // CHECK-NEXT: "testvar.var_operand"(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) : (i16, i32, i32, i32, i64) -> ()
- return
-}
-
-// -----
-
-// Check that the verifier of a variadic operand fails if the variadic is given
-// a wrong type.
-func.func @testVarOperandFail(%x: i16, %y: i64, %z: i64) {
- // expected-error at +1 {{expected 'i32' but got 'i64'}}
- "testvar.var_operand"(%x, %y, %z) : (i16, i64, i64) -> ()
- return
-}
-
-// -----
-
-// Check that the verifier of a variadic operand fails if the variadic is given
-// a wrong type on the second value.
-func.func @testVarOperandFail(%x: i16, %y1: i32, %y2: i64, %z: i64) {
- // expected-error at +1 {{expected 'i32' but got 'i64'}}
- "testvar.var_operand"(%x, %y1, %y2, %z) : (i16, i32, i64, i64) -> ()
- return
-}
-
-// -----
-
-// Check that if we do not give enough operands, the verifier fails.
-func.func @testVarOperandFail() {
- // expected-error at +1 {{op expects at least 2 operands, but got 0}}
- "testvar.var_operand"() : () -> ()
- return
-}
-
-// -----
-
-//===----------------------------------------------------------------------===//
-// Optional operand
-//===----------------------------------------------------------------------===//
-
-
-// Test an operation with a single optional operand.
-func.func @testOptOperand(%x: i16, %y: i32, %z: i64) {
- "testvar.opt_operand"(%x, %z) : (i16, i64) -> ()
- // CHECK: "testvar.opt_operand"(%{{.*}}, %{{.*}}) : (i16, i64) -> ()
- "testvar.opt_operand"(%x, %y, %z) : (i16, i32, i64) -> ()
- // CHECK-NEXT: "testvar.opt_operand"(%{{.*}}, %{{.*}}, %{{.*}}) : (i16, i32, i64) -> ()
- return
-}
-
-// -----
-
-// Check that the verifier of an optional operand fails if the variadic is
-// given a wrong type.
-func.func @testOptOperandFail(%x: i16, %y: i64, %z: i64) {
- // expected-error at +1 {{expected 'i32' but got 'i64'}}
- "testvar.opt_operand"(%x, %y, %z) : (i16, i64, i64) -> ()
- return
-}
-
-// -----
-
-// Check that the verifier of an optional operand fails if there are too
-// many operands.
-func.func @testOptOperandFail(%x: i16, %y: i32, %z: i64) {
- // expected-error at +1 {{op expects at most 3 operands, but got 4}}
- "testvar.opt_operand"(%x, %y, %y, %z) : (i16, i32, i32, i64) -> ()
- return
-}
-
-// -----
-
-// Check that the verifier of an optional operand fails if there are not
-// enough operands.
-func.func @testOptOperandFail(%x: i16) {
- // expected-error at +1 {{op expects at least 2 operands, but got 1}}
- "testvar.opt_operand"(%x) : (i16) -> ()
- return
-}
-
-// -----
-
-//===----------------------------------------------------------------------===//
-// Multiple variadic
-//===----------------------------------------------------------------------===//
-
-// Check that an operation with multiple variadics expects the segment size
-// attribute
-func.func @testMultOperandsMissingSegment(%x: i16, %z: i64) {
- // expected-error at +1 {{'operand_segment_sizes' attribute is expected but not provided}}
- "testvar.var_and_opt_operand"(%x, %x, %z) : (i16, i16, i64) -> ()
- return
-}
-
-// -----
-
-// Check that an operation with multiple variadics expects the segment size
-// attribute of the right type
-func.func @testMultOperandsWrongSegmentType(%x: i16, %z: i64) {
- // expected-error at +1 {{'operand_segment_sizes' attribute is expected to be a dense i32 array}}
- "testvar.var_and_opt_operand"(%x, %x, %z) {operand_segment_sizes = i32} : (i16, i16, i64) -> ()
- return
-}
-
-// -----
-
-// Check that an operation with multiple variadics with the right segment size
-// verifies.
-func.func @testMultOperands(%x: i16, %y: i32, %z: i64) {
- "testvar.var_and_opt_operand"(%x, %x, %z) {operand_segment_sizes = array<i32: 2, 0, 1>} : (i16, i16, i64) -> ()
- // CHECK: "testvar.var_and_opt_operand"(%{{.*}}, %{{.*}}, %{{.*}}) {operand_segment_sizes = array<i32: 2, 0, 1>} : (i16, i16, i64) -> ()
- "testvar.var_and_opt_operand"(%x, %x, %y, %z) {operand_segment_sizes = array<i32: 2, 1, 1>} : (i16, i16, i32, i64) -> ()
- // CHECK-NEXT: "testvar.var_and_opt_operand"(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {operand_segment_sizes = array<i32: 2, 1, 1>} : (i16, i16, i32, i64) -> ()
- "testvar.var_and_opt_operand"(%y, %z) {operand_segment_sizes = array<i32: 0, 1, 1>} : (i32, i64) -> ()
- // CHECK-NEXT: "testvar.var_and_opt_operand"(%{{.*}}, %{{.*}}) {operand_segment_sizes = array<i32: 0, 1, 1>} : (i32, i64) -> ()
- return
-}
-
-// -----
-
-// Check that the segment sizes expects non-negative values
-func.func @testMultOperandsSegmentNegative() {
- // expected-error at +1 {{'operand_segment_sizes' attribute for specifying operand segments must have non-negative values}}
- "testvar.var_and_opt_operand"() {operand_segment_sizes = array<i32: 2, -1, 1>} : () -> ()
- return
-}
-
-// -----
-
-// Check that the segment sizes expects 1 for single values
-func.func @testMultOperandsSegmentWrongSingle() {
- // expected-error at +1 {{element 2 in 'operand_segment_sizes' attribute must be equal to 1}}
- "testvar.var_and_opt_operand"() {operand_segment_sizes = array<i32: 0, 0, 0>} : () -> ()
- return
-}
-
-// -----
-
-// Check that the segment sizes expects not more than 1 for optional values
-func.func @testMultOperandsSegmentWrongOptional() {
- // expected-error at +1 {{element 1 in 'operand_segment_sizes' attribute must be equal to 0 or 1}}
- "testvar.var_and_opt_operand"() {operand_segment_sizes = array<i32: 0, 2, 0>} : () -> ()
- return
-}
-
-// -----
-
-// Check that the sum of the segment sizes should be equal to the number of operands
-func.func @testMultOperandsSegmentWrongOptional(%y: i32, %z: i64) {
- // expected-error at +1 {{sum of elements in 'operand_segment_sizes' attribute must be equal to the number of operands}}
- "testvar.var_and_opt_operand"(%y, %z) {operand_segment_sizes = array<i32: 0, 0, 1>} : (i32, i64) -> ()
- return
-}
-
-// -----
-
-//===----------------------------------------------------------------------===//
-// Single result
-//===----------------------------------------------------------------------===//
-
-// Test an operation with a single result.
-func.func @testSingleResult() {
- %x = "testvar.single_result"() : () -> i32
- // CHECK: %{{.*}} = "testvar.single_result"() : () -> i32
- return
-}
-
-// -----
-
-// Test an operation with a single result definition and a wrong number of results.
-func.func @testSingleResultFail() {
- // expected-error at +1 {{op expects exactly 1 results, but got 2}}
- %x, %y = "testvar.single_result"() : () -> (i32, i32)
- return
-}
-
-// -----
-
-// Test an operation with a single result definition and a wrong number of results.
-func.func @testSingleResultFail() {
- // expected-error at +1 {{op expects exactly 1 results, but got 0}}
- "testvar.single_result"() : () -> ()
- return
-}
-
-// -----
-
-
-//===----------------------------------------------------------------------===//
-// Variadic result
-//===----------------------------------------------------------------------===//
-
-
-// Test an operation with a single variadic result.
-func.func @testVarResult() {
- "testvar.var_result"() : () -> (i16, i64)
- // CHECK: "testvar.var_result"() : () -> (i16, i64)
- "testvar.var_result"() : () -> (i16, i32, i64)
- // CHECK-NEXT: "testvar.var_result"() : () -> (i16, i32, i64)
- "testvar.var_result"() : () -> (i16, i32, i32, i64)
- // CHECK-NEXT: "testvar.var_result"() : () -> (i16, i32, i32, i64)
- "testvar.var_result"() : () -> (i16, i32, i32, i32, i64)
- // CHECK-NEXT: "testvar.var_result"() : () -> (i16, i32, i32, i32, i64)
- return
-}
-
-// -----
-
-// Check that the verifier of a variadic result fails if the variadic is given
-// a wrong type.
-func.func @testVarResultFail() {
- // expected-error at +1 {{expected 'i32' but got 'i64'}}
- "testvar.var_result"() : () -> (i16, i64, i64)
- return
-}
-
-// -----
-
-// Check that the verifier of a variadic result fails if the variadic is given
-// a wrong type on the second value.
-func.func @testVarResultFail() {
- // expected-error at +1 {{expected 'i32' but got 'i64'}}
- "testvar.var_result"() : () -> (i16, i32, i64, i64)
- return
-}
-
-// -----
-
-// Check that if we do not give enough results, the verifier fails.
-func.func @testVarResultFail() {
- // expected-error at +1 {{op expects at least 2 results, but got 0}}
- "testvar.var_result"() : () -> ()
- return
-}
-
-// -----
-
-//===----------------------------------------------------------------------===//
-// Optional result
-//===----------------------------------------------------------------------===//
-
-
-// Test an operation with a single optional result.
-func.func @testOptResult() {
- "testvar.opt_result"() : () -> (i16, i64)
- // CHECK: "testvar.opt_result"() : () -> (i16, i64)
- "testvar.opt_result"() : () -> (i16, i32, i64)
- // CHECK-NEXT: "testvar.opt_result"() : () -> (i16, i32, i64)
- return
-}
-
-// -----
-
-// Check that the verifier of an optional result fails if the variadic is
-// given a wrong type.
-func.func @testOptResultFail() {
- // expected-error at +1 {{expected 'i32' but got 'i64'}}
- "testvar.opt_result"() : () -> (i16, i64, i64)
- return
-}
-
-// -----
-
-// Check that the verifier of an optional result fails if there are too
-// many results.
-func.func @testOptResultFail() {
- // expected-error at +1 {{op expects at most 3 results, but got 4}}
- "testvar.opt_result"() : () -> (i16, i32, i32, i64)
- return
-}
-
-// -----
-
-// Check that the verifier of an optional result fails if there are not
-// enough results.
-func.func @testOptResultFail() {
- // expected-error at +1 {{op expects at least 2 results, but got 1}}
- "testvar.opt_result"() : () -> (i16)
- return
-}
-
-// -----
-
-//===----------------------------------------------------------------------===//
-// Multiple variadic
-//===----------------------------------------------------------------------===//
-
-// Check that an operation with multiple variadics expects the segment size
-// attribute
-func.func @testMultResultsMissingSegment() {
- // expected-error at +1 {{'result_segment_sizes' attribute is expected but not provided}}
- "testvar.var_and_opt_result"() : () -> (i16, i16, i64)
- return
-}
-
-// -----
-
-// Check that an operation with multiple variadics expects the segment size
-// attribute of the right type
-func.func @testMultResultsWrongSegmentType() {
- // expected-error at +1 {{'result_segment_sizes' attribute is expected to be a dense i32 array}}
- "testvar.var_and_opt_result"() {result_segment_sizes = i32} : () -> (i16, i16, i64)
- return
-}
-
-// -----
-
-// Check that an operation with multiple variadics with the right segment size
-// verifies.
-func.func @testMultResults() {
- "testvar.var_and_opt_result"() {result_segment_sizes = array<i32: 2, 0, 1>} : () -> (i16, i16, i64)
- // CHECK: "testvar.var_and_opt_result"() {result_segment_sizes = array<i32: 2, 0, 1>} : () -> (i16, i16, i64)
- "testvar.var_and_opt_result"() {result_segment_sizes = array<i32: 2, 1, 1>} : () -> (i16, i16, i32, i64)
- // CHECK-NEXT: "testvar.var_and_opt_result"() {result_segment_sizes = array<i32: 2, 1, 1>} : () -> (i16, i16, i32, i64)
- "testvar.var_and_opt_result"() {result_segment_sizes = array<i32: 0, 1, 1>} : () -> (i32, i64)
- // CHECK-NEXT: "testvar.var_and_opt_result"() {result_segment_sizes = array<i32: 0, 1, 1>} : () -> (i32, i64)
- return
-}
-
-// -----
-
-// Check that the segment sizes expects non-negative values
-func.func @testMultResultsSegmentNegative() {
- // expected-error at +1 {{'result_segment_sizes' attribute for specifying result segments must have non-negative values}}
- "testvar.var_and_opt_result"() {result_segment_sizes = array<i32: 2, -1, 1>} : () -> ()
- return
-}
-
-// -----
-
-// Check that the segment sizes expects 1 for single values
-func.func @testMultResultsSegmentWrongSingle() {
- // expected-error at +1 {{element 2 in 'result_segment_sizes' attribute must be equal to 1}}
- "testvar.var_and_opt_result"() {result_segment_sizes = array<i32: 0, 0, 0>} : () -> ()
- return
-}
-
-// -----
-
-// Check that the segment sizes expects not more than 1 for optional values
-func.func @testMultResultsSegmentWrongOptional() {
- // expected-error at +1 {{element 1 in 'result_segment_sizes' attribute must be equal to 0 or 1}}
- "testvar.var_and_opt_result"() {result_segment_sizes = array<i32: 0, 2, 0>} : () -> ()
- return
-}
-
-// -----
-
-// Check that the sum of the segment sizes should be equal to the number of results
-func.func @testMultResultsSegmentWrongOptional() {
- // expected-error at +1 {{sum of elements in 'result_segment_sizes' attribute must be equal to the number of results}}
- "testvar.var_and_opt_result"() {result_segment_sizes = array<i32: 0, 0, 1>} : () -> (i32, i64)
- return
-}
More information about the Mlir-commits
mailing list