blob: 0218ae6e81ac599003c177034c4c79777e9cc8aa [file] [edit]
// RUN: mlir-opt %s -verify-diagnostics -split-input-file | FileCheck %s
// Tests for the builtin `token` type, the token producer/consumer operation
// traits, and the `Token`, `AnyType` ODS predicates. The default `AnyType`
// predicate excludes tokens.
// CHECK-LABEL: @token_produce_consume
func.func @token_produce_consume() {
// CHECK: %[[T:.*]] = test.token.produce
%t = test.token.produce
// CHECK: test.token.consume %[[T]]
test.token.consume %t
return
}
// -----
// Region entry block arguments may produce tokens when the parent op opts in.
// CHECK-LABEL: @token_region_entry_block_arg
func.func @token_region_entry_block_arg() {
// CHECK: "test.token.region"
"test.token.region"() ({
^bb0(%arg0: token):
// CHECK: test.token.consume
test.token.consume %arg0
"test.finish"() : () -> ()
}) : () -> ()
return
}
// -----
// `AnyType` accepts arbitrary non-token types.
// CHECK-LABEL: @any_type_with_non_token
func.func @any_type_with_non_token(%arg0: i32) {
// CHECK: test.token.any_type %{{.*}} : i32
test.token.any_type %arg0 : i32
return
}
// -----
// `AnyType` rejects tokens by default.
func.func @any_type_rejects_token() {
%t = test.token.produce
// expected-error @below {{operand #0 must be any non-token type}}
test.token.any_type %t : token
return
}
// -----
// Token-producing ops must have the TokenProducerTrait.
func.func @token_result_requires_producer_trait() {
// expected-error @below {{'test.token.produce_without_trait' op produces token result #0 but does not have the TokenProducerTrait}}
%t = test.token.produce_without_trait : token
return
}
// -----
// Token-consuming ops must have the TokenConsumerTrait.
func.func @token_operand_requires_consumer_trait() {
%t = test.token.produce
// expected-error @below {{'test.token.consume_without_trait' op consumes token operand #0 but does not have the TokenConsumerTrait}}
test.token.consume_without_trait %t : token
return
}
// -----
// Token entry block arguments require the parent op to have the
// TokenProducerTrait.
func.func @token_entry_block_arg_requires_parent_producer_trait() {
"test.token.region_without_trait"() ({
// expected-error @below {{token entry block argument #0 requires the parent operation to have the TokenProducerTrait}}
^bb0(%arg0: token):
test.token.consume %arg0
"test.finish"() : () -> ()
}) : () -> ()
return
}
// -----
// A region with a parent op still cannot have token entry block arguments unless
// the parent op has the TokenProducerTrait.
func.func @token_entry_block_arg_requires_parent_producer_trait_without_uses() {
"test.token.region_without_trait"() ({
// expected-error @below {{token entry block argument #0 requires the parent operation to have the TokenProducerTrait}}
^bb0(%arg0: token):
"test.finish"() : () -> ()
}) : () -> ()
return
}
// -----
// Token entry block arguments still require consumers to have the
// TokenConsumerTrait.
func.func @token_entry_block_arg_use_requires_consumer_trait() {
"test.token.region"() ({
^bb0(%arg0: token):
// expected-error @below {{'test.token.consume_without_trait' op consumes token operand #0 but does not have the TokenConsumerTrait}}
test.token.consume_without_trait %arg0 : token
"test.finish"() : () -> ()
}) : () -> ()
return
}
// -----
// Tokens cannot be non-entry block arguments.
func.func @token_non_entry_block_arg_is_rejected() {
"test.token.region"() ({
"test.finish"() : () -> ()
// expected-error @below {{token block argument #0 is only allowed in a region entry block}}
^bb1(%arg0: token):
"test.finish"() : () -> ()
}) : () -> ()
return
}
// -----
// Function entry blocks do not opt in to producing builtin tokens.
// expected-error @below {{token entry block argument #0 requires the parent operation to have the TokenProducerTrait}}
func.func @token_region_arg(%arg0: token) {
test.token.consume %arg0
return
}
// -----
// `Token` rejects non-token types. The op's operand type is fixed to the
// builtin `token` (it's a `BuildableType`), so passing a non-token SSA value
// fails at parse time with an SSA type mismatch.
// expected-note @below {{prior use here}}
func.func @token_rejects_non_token(%arg0: i32) {
// expected-error @below {{use of value '%arg0' expects different type than prior uses: 'token' vs 'i32'}}
test.token.consume %arg0
return
}