// given type.
class ArgOrResultElementTypeIs<string name, Type type> : And<[
SubstLeaves<"$_self", "$" # name # ".getType()", IsShapedTypePred>,
- SubstLeaves<"$_self", "$" # name #
- ".getType().cast<ShapedType>().getElementType()",
+ SubstLeaves<"$_self", "mlir::getElementTypeOrSelf($" # name # ")",
type.predicate>]>;
// Predicate to verify that the i'th operand and the j'th operand have the same
// Type Constraint operand `i`'s Element type is Same As operand `j`'s Element
// type.
class TCopVTEtIsSameAs<int i, int j> : And<[
- CPred<"$_op.getNumOperands() > std::max(" # i # "," # j # ")">,
+ CPred<"$_op.getNumOperands() > std::max(" # i # "u," # j # "u)">,
SubstLeaves<"$_self", "$_op.getOperand(" # i # ")->getType()",
IsShapedTypePred>,
SubstLeaves<"$_self", "$_op.getOperand(" # j # ")->getType()",
IsShapedTypePred>,
- // TODO: This could be made into C++ function instead.
- CPred<"$_op.getOperand(" # i # ")->getType().cast<ShapedType>()."
- "getElementType() == $_op.getOperand(" # j # ")->getType()."
- "cast<ShapedType>().getElementType()">]>;
+ CPred<"mlir::getElementTypeOrSelf($_op.getOperand(" # i # ")) == "
+ "mlir::getElementTypeOrSelf($_op.getOperand(" # j # "))">]>;
// Predicate to verify that the i'th result and the j'th operand have the same
// elemental type.
--- /dev/null
+//===- TypeUtilities.h - Helper function for type queries -------*- C++ -*-===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+//
+// This file defines generic type utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_SUPPORT_TYPEUTILITIES_H
+#define MLIR_SUPPORT_TYPEUTILITIES_H
+
+namespace mlir {
+
+class Attribute;
+class Type;
+class Value;
+
+/// Return the element type or return the type itself.
+Type getElementTypeOrSelf(Type type);
+
+/// Return the element type or return the type itself.
+Type getElementTypeOrSelf(Attribute attr);
+Type getElementTypeOrSelf(Value *val);
+Type getElementTypeOrSelf(Value &val);
+
+} // end namespace mlir
+
+#endif // MLIR_SUPPORT_TYPEUTILITIES_H
+set(LLVM_OPTIONAL_SOURCES
+ FileUtilities.cpp
+ StorageUniquer.cpp
+ TypeUtilities.cpp
+)
+
add_llvm_library(MLIRSupport
FileUtilities.cpp
StorageUniquer.cpp
${MLIR_MAIN_INCLUDE_DIR}/mlir/Support
)
target_link_libraries(MLIRSupport LLVMSupport)
+
+add_llvm_library(MLIRTypeUtilities
+ TypeUtilities.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ ${MLIR_MAIN_INCLUDE_DIR}/mlir/Support
+ )
+target_link_libraries(MLIRTypeUtilities MLIRIR MLIRStandardOps)
--- /dev/null
+//===- TypeUtilities.h - Helper function for type queries -----------------===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+//
+// This file defines generic type utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Support/TypeUtilities.h"
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/StandardTypes.h"
+#include "mlir/IR/Types.h"
+#include "mlir/IR/Value.h"
+
+using namespace mlir;
+
+Type mlir::getElementTypeOrSelf(Type type) {
+ if (auto st = type.dyn_cast<ShapedType>())
+ return st.getElementType();
+ return type;
+}
+
+Type mlir::getElementTypeOrSelf(Value *val) {
+ return getElementTypeOrSelf(val->getType());
+}
+
+Type mlir::getElementTypeOrSelf(Value &val) {
+ return getElementTypeOrSelf(val.getType());
+}
+
+Type mlir::getElementTypeOrSelf(Attribute attr) {
+ return getElementTypeOrSelf(attr.getType());
+}
target_link_libraries(mlir-test-opt
PRIVATE
MLIRMlirOptLib
+ MLIRTypeUtilities
LLVMSupport
)
#include "TestDialect.h"
#include "mlir/IR/PatternMatch.h"
+#include "mlir/Support/TypeUtilities.h"
using namespace mlir;
let results = (outs AnyVectorOrTensor:$res);
}
+def OperandsHaveSameElementType : TEST_Op<"operands_have_same_element_type", [
+ PredOpTrait<"first and second operand have same element type",
+ TCopVTEtIsSameAs<0, 1>>]> {
+ let arguments = (ins AnyTensor:$x, AnyTensor:$y);
+}
+
//===----------------------------------------------------------------------===//
// Test Patterns
//===----------------------------------------------------------------------===//
// CHECK-LABEL: OpC::verify
// CHECK: if (!((((*this->getOperation()).getNumOperands() > 0)) && (((*this->getOperation()).getOperand(0)->getType().isa<ShapedType>())) && (((*this->getOperation()).getOperand(0)->getType().cast<ShapedType>().getElementType().isInteger(32)))))
-
-def OpD : NS_Op<"op_for_TCOpVTEtIsSameAs", [
- PredOpTrait<"first operand is a shaped type with the same "
- "elemental type as itself",
- TCopVTEtIsSameAs<0, 0>>]> {
- let arguments = (ins AnyTensor:$x);
-}
-
-// CHECK-LABEL: OpD::verify
-// CHECK: if (!((((*this->getOperation()).getNumOperands() > std::max(0,0))) && (((*this->getOperation()).getOperand(0)->getType().isa<ShapedType>())) && (((*this->getOperation()).getOperand(0)->getType().isa<ShapedType>())) && (((*this->getOperation()).getOperand(0)->getType().cast<ShapedType>().getElementType() == (*this->getOperation()).getOperand(0)->getType().cast<ShapedType>().getElementType()))))
-// CHECK-NEXT: return emitOpError("failed to verify that first operand is a shaped type with the same elemental type as itself");
-
-
def OpE : NS_Op<"op_for_TCresVTEtIsSameAsOp", [
PredOpTrait<"first operand is a shaped type with the same "
"elemental type as first result",
%0 = "test.arg_and_res_have_fixed_element_types"(%arg1, %arg0) {attr: ""}: (tensor<* x f32>, tensor<* x i32>) -> tensor<* x i16>
return
}
+
+// -----
+
+func @fixed_element_types(%arg0: tensor<* x i32>, %arg1: tensor<* x f32>) {
+ // expected-error@+1 {{failed to verify that first and second operand have same element type}}
+ "test.operands_have_same_element_type"(%arg1, %arg0): (tensor<* x f32>, tensor<* x i32>) -> ()
+ return
+}