| // 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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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@+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 |
| } |