diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -565,11 +565,15 @@ def LLVM_GlobalOp : LLVM_ZeroResultOp<"mlir.global", [IsolatedFromAbove, - SingleBlockImplicitTerminator<"ReturnOp">, Symbol]>, - Arguments<(ins TypeAttr:$type, UnitAttr:$constant, StrAttr:$sym_name, - Linkage:$linkage, - OptionalAttr:$value, - DefaultValuedAttr:$addr_space)> { + SingleBlockImplicitTerminator<"ReturnOp">, Symbol]> { + let arguments = (ins + TypeAttr:$type, + UnitAttr:$constant, + StrAttr:$sym_name, + Linkage:$linkage, + OptionalAttr:$value, + DefaultValuedAttr, "0">:$addr_space + ); let summary = "LLVM dialect global."; let description = [{ Can contain an optional initializer region or attribute for simple diff --git a/mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td b/mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td --- a/mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td +++ b/mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td @@ -63,7 +63,7 @@ list cases> : BitEnumAttr { let predicate = And<[ - IntegerAttrBase.predicate, + I32Attr.predicate, SPV_IsKnownEnumCaseFor, ]>; let cppNamespace = "::mlir::spirv"; @@ -74,7 +74,7 @@ list cases> : I32EnumAttr { let predicate = And<[ - IntegerAttrBase.predicate, + I32Attr.predicate, SPV_IsKnownEnumCaseFor, ]>; let cppNamespace = "::mlir::spirv"; @@ -2955,7 +2955,7 @@ def SPV_Void : TypeAlias; def SPV_Bool : I<1>; -def SPV_Integer : IntOfWidths<[8, 16, 32, 64]>; +def SPV_Integer : AnyIntOfWidths<[8, 16, 32, 64]>; def SPV_Float : FloatOfWidths<[16, 32, 64]>; def SPV_Float16or32 : FloatOfWidths<[16, 32]>; def SPV_Vector : VectorOfLengthAndType<[2, 3, 4], diff --git a/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td b/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td --- a/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td +++ b/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td @@ -1770,7 +1770,8 @@ This operation doesn't affect the semantics of a correct program. It's for optimization only, and the optimization is best-effort. }]; - let arguments = (ins AnyMemRef:$memref, PositiveI32Attr:$alignment); + let arguments = (ins AnyMemRef:$memref, + Confined:$alignment); let results = (outs); let assemblyFormat = "$memref `,` $alignment attr-dict `:` type($memref)"; diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td --- a/mlir/include/mlir/IR/OpBase.td +++ b/mlir/include/mlir/IR/OpBase.td @@ -313,25 +313,41 @@ description)>; // Integer types. -// Any integer type irrespective of its width. -def AnySignlessInteger : Type< - CPred<"$_self.isSignlessInteger()">, "integer">; -// Index type. -def Index : Type()">, "index">, - BuildableType<"$_builder.getIndexType()">; +// Any integer type irrespective of its width and signedness semantics. +def AnyInteger : Type, "integer">; + +// Any integer type (regardless of signedness semantics) of a specific width. +class AnyI + : Type, width # "-bit integer"> { + int bitwidth = width; +} -// Integer type of a specific width. +class AnyIntOfWidths widths> : + AnyTypeOf), + StrJoinInt.result # "-bit integer">; + +def AnyI1 : AnyI<1>; +def AnyI8 : AnyI<8>; +def AnyI16 : AnyI<16>; +def AnyI32 : AnyI<32>; +def AnyI64 : AnyI<64>; + +// Any signless integer type irrespective of its width. +def AnySignlessInteger : Type< + CPred<"$_self.isSignlessInteger()">, "signless integer">; + +// Signless integer type of a specific width. class I : Type, - width # "-bit integer">, + width # "-bit signless integer">, BuildableType<"$_builder.getIntegerType(" # width # ")"> { int bitwidth = width; } -class IntOfWidths widths> : +class SignlessIntOfWidths widths> : AnyTypeOf), - StrJoinInt.result # "-bit integer">; + StrJoinInt.result # "-bit signless integer">; def I1 : I<1>; def I8 : I<8>; @@ -339,7 +355,29 @@ def I32 : I<32>; def I64 : I<64>; -// Unsigned integer types. +// Any signed integer type irrespective of its width. +def AnySignedInteger : Type< + CPred<"$_self.isSignedInteger()">, "signed integer">; + +// Signed integer type of a specific width. +class SI + : Type, + width # "-bit signed integer">, + BuildableType< + "$_builder.getIntegerType(" # width # ", /*isSigned=*/true)"> { + int bitwidth = width; +} + +class SignedIntOfWidths widths> : + AnyTypeOf), + StrJoinInt.result # "-bit signed integer">; + +def SI1 : SI<1>; +def SI8 : SI<8>; +def SI16 : SI<16>; +def SI32 : SI<32>; +def SI64 : SI<64>; + // Any unsigned integer type irrespective of its width. def AnyUnsignedInteger : Type< CPred<"$_self.isUnsignedInteger()">, "unsigned integer">; @@ -348,8 +386,8 @@ class UI : Type, width # "-bit unsigned integer">, - BuildableType<"$_builder.getIntegerType(" # width # - ", /*isSigned=*/false)"> { + BuildableType< + "$_builder.getIntegerType(" # width # ", /*isSigned=*/false)"> { int bitwidth = width; } @@ -363,6 +401,10 @@ def UI32 : UI<32>; def UI64 : UI<64>; +// Index type. +def Index : Type()">, "index">, + BuildableType<"$_builder.getIndexType()">; + // Floating point types. // Any float type irrespective of its width. @@ -613,23 +655,23 @@ TensorOf<[I1]>.predicate]>, "bool-like">; -// Type constraint for integer-like types: integers, indices, vectors of -// integers, tensors of integers. +// Type constraint for signless-integer-like types: signless integers, indices, +// vectors of signless integers, tensors of signless integers. def SignlessIntegerLike : TypeConstraint.predicate, TensorOf<[AnySignlessInteger]>.predicate]>, - "integer-like">; + "signless-integer-like">; // Type constraint for float-like types: floats, vectors or tensors thereof. def FloatLike : TypeConstraint.predicate, TensorOf<[AnyFloat]>.predicate]>, "floating-point-like">; -// Type constraint for integer-like or float-like types. +// Type constraint for signless-integer-like or float-like types. def SignlessIntegerOrFloatLike : TypeConstraint, - "integer-like or floating-point-like">; + "signless-integer-like or floating-point-like">; //===----------------------------------------------------------------------===// @@ -750,57 +792,91 @@ let constBuilderCall = "$_builder.getBoolAttr($0)"; } -// Base class for integer attributes of fixed width. -class IntegerAttrBase : +// Base class for any integer (regardless of signedness semantics) attributes +// of fixed width. +class AnyIntegerAttrBase : TypedAttrBase< attrValType, "IntegerAttr", And<[CPred<"$_self.isa()">, CPred<"$_self.cast().getType()." - "isSignlessInteger(" # attrValType.bitwidth # ")">]>, + "isInteger(" # attrValType.bitwidth # ")">]>, descr> { let returnType = [{ APInt }]; + let constBuilderCall = ?; } +def AnyI1Attr : AnyIntegerAttrBase; +def AnyI8Attr : AnyIntegerAttrBase; +def AnyI16Attr : AnyIntegerAttrBase; +def AnyI32Attr : AnyIntegerAttrBase; +def AnyI64Attr : AnyIntegerAttrBase; + def APIntAttr : Attr()">, "arbitrary integer attribute"> { let storageType = [{ IntegerAttr }]; let returnType = [{ APInt }]; } -def I1Attr : IntegerAttrBase; -def I8Attr : IntegerAttrBase; -def I16Attr : IntegerAttrBase; -def I32Attr : IntegerAttrBase; -def I64Attr : IntegerAttrBase; +// Base class for signless integer attributes of fixed width. +class SignlessIntegerAttrBase : + TypedAttrBase< + attrValType, "IntegerAttr", + And<[CPred<"$_self.isa()">, + CPred<"$_self.cast().getType()." + "isSignlessInteger(" # attrValType.bitwidth # ")">]>, + descr> { + let returnType = [{ APInt }]; +} + +def I1Attr : SignlessIntegerAttrBase; +def I8Attr : SignlessIntegerAttrBase; +def I16Attr : SignlessIntegerAttrBase; +def I32Attr : SignlessIntegerAttrBase; +def I64Attr : SignlessIntegerAttrBase; -class NonNegativeIntAttrBase : +// Base class for signed integer attributes of fixed width. +class SignedIntegerAttrBase : TypedAttrBase< attrValType, "IntegerAttr", - And<[IntegerAttrBase.predicate, - CPred<"!$_self.cast().getValue().isNegative()">]>, + And<[CPred<"$_self.isa()">, + CPred<"$_self.cast().getType()." + "isSignedInteger(" # attrValType.bitwidth # ")">]>, descr> { let returnType = [{ APInt }]; } -def NonNegativeI32Attr : NonNegativeIntAttrBase< - I32, "non-negative 32-bit integer attribute">; -def NonNegativeI64Attr : NonNegativeIntAttrBase< - I64, "non-negative 64-bit integer attribute">; +def SI1Attr : SignedIntegerAttrBase< + SI1, "1-bit signed integer attribute">; +def SI8Attr : SignedIntegerAttrBase< + SI8, "8-bit signed integer attribute">; +def SI16Attr : SignedIntegerAttrBase< + SI16, "16-bit signed integer attribute">; +def SI32Attr : SignedIntegerAttrBase< + SI32, "32-bit signed integer attribute">; +def SI64Attr : SignedIntegerAttrBase< + SI64, "64-bit signed integer attribute">; -class PositiveIntAttrBase : +// Base class for unsigned integer attributes of fixed width. +class UnsignedIntegerAttrBase : TypedAttrBase< attrValType, "IntegerAttr", - And<[IntegerAttrBase.predicate, - CPred<"$_self.cast().getValue()" - ".isStrictlyPositive()">]>, + And<[CPred<"$_self.isa()">, + CPred<"$_self.cast().getType()." + "isUnsignedInteger(" # attrValType.bitwidth # ")">]>, descr> { let returnType = [{ APInt }]; } -def PositiveI32Attr : PositiveIntAttrBase< - I32, "positive 32-bit integer attribute">; -def PositiveI64Attr : PositiveIntAttrBase< - I64, "positive 64-bit integer attribute">; +def UI1Attr : UnsignedIntegerAttrBase< + UI1, "1-bit unsigned integer attribute">; +def UI8Attr : UnsignedIntegerAttrBase< + UI8, "8-bit unsigned integer attribute">; +def UI16Attr : UnsignedIntegerAttrBase< + UI16, "16-bit unsigned integer attribute">; +def UI32Attr : UnsignedIntegerAttrBase< + UI32, "32-bit unsigned integer attribute">; +def UI64Attr : UnsignedIntegerAttrBase< + UI64, "64-bit unsigned integer attribute">; // Base class for float attributes of fixed width. class FloatAttrBase : @@ -879,7 +955,7 @@ // its representation as a string and a C++ symbol name which may be different. class IntEnumAttrCaseBase : EnumAttrCaseInfo, - IntegerAttrBase { + SignlessIntegerAttrBase { let predicate = CPred<"$_self.cast().getInt() == " # intVal>; } @@ -896,7 +972,7 @@ // one bit set. class BitEnumAttrCase : EnumAttrCaseInfo, - IntegerAttrBase { + SignlessIntegerAttrBase { let predicate = CPred< "$_self.cast().getValue().getZExtValue() & " # val # "u">; } @@ -982,11 +1058,11 @@ class IntEnumAttr cases> : EnumAttrInfo, - IntegerAttrBase.result, description)> { let predicate = And<[ - IntegerAttrBase.predicate, + SignlessIntegerAttrBase.predicate, Or]>; } @@ -1015,9 +1091,9 @@ // delimiter to a symbol and vice versa. class BitEnumAttr cases> : - EnumAttrInfo, IntegerAttrBase { + EnumAttrInfo, SignlessIntegerAttrBase { let predicate = And<[ - IntegerAttrBase.predicate, + I32Attr.predicate, // Make sure we don't have unknown bit set. CPred<"!($_self.cast().getValue().getZExtValue() & (~(" # StrJoin.result # @@ -1057,37 +1133,51 @@ } def ElementsAttr : ElementsAttrBase()">, - "constant vector/tensor attribute">; - -class IntElementsAttr : ElementsAttrBase< - CPred<"$_self.isa() &&" - "$_self.cast().getType()." - "getElementType().isSignlessInteger(" # width # ")">, - width # "-bit integer elements attribute"> { + "constant vector/tensor attribute">; +class IntElementsAttrBase : + ElementsAttrBase()">, + condition]>, + description> { let storageType = [{ DenseIntElementsAttr }]; let returnType = [{ DenseIntElementsAttr }]; + let convertFromStorage = "$_self"; +} + +class AnyIntElementsAttr : IntElementsAttrBase< + CPred<"$_self.cast().getType()." + "getElementType().isInteger(" # width # ")">, + width # "-bit integer elements attribute">; + +def AnyI32ElementsAttr : AnyIntElementsAttr<32>; +def AnyI64ElementsAttr : AnyIntElementsAttr<64>; + +class SignlessIntElementsAttr : IntElementsAttrBase< + CPred<"$_self.cast().getType()." + "getElementType().isSignlessInteger(" # width # ")">, + width # "-bit signless integer elements attribute"> { + // Note that this is only constructing scalar elements attribute. let constBuilderCall = "DenseElementsAttr::get(" "RankedTensorType::get({}, $_builder.getIntegerType(" # width # ")), " "llvm::makeArrayRef($0)).cast()"; - let convertFromStorage = "$_self"; } -def I32ElementsAttr : IntElementsAttr<32>; -def I64ElementsAttr : IntElementsAttr<64>; +def I32ElementsAttr : SignlessIntElementsAttr<32>; +def I64ElementsAttr : SignlessIntElementsAttr<64>; -// A `width`-bit integer elements attribute. The attribute should be ranked and -// has a shape as specified in `dims`. -class RankedIntElementsAttr dims> : IntElementsAttr { +// A `width`-bit signless integer elements attribute. The attribute should be +// ranked and has a shape as specified in `dims`. +class RankedSignlessIntElementsAttr dims> : + SignlessIntElementsAttr { // Check that this has the specified shape. let predicate = And<[ - IntElementsAttr.predicate, + SignlessIntElementsAttr.predicate, CPred<"$_self.cast().getType().getShape() == " "ArrayRef({" # StrJoinInt.result # "})">]>; - let description = width # "-bit int elements attribute of shape [" # + let description = width # "-bit signless int elements attribute of shape [" # StrJoinInt.result # "]"; let constBuilderCall = "DenseIntElementsAttr::get(" @@ -1095,8 +1185,10 @@ "}, $_builder.getIntegerType(" # width # ")), makeArrayRef($0))"; } -class RankedI32ElementsAttr dims> : RankedIntElementsAttr<32, dims>; -class RankedI64ElementsAttr dims> : RankedIntElementsAttr<64, dims>; +class RankedI32ElementsAttr dims> : + RankedSignlessIntElementsAttr<32, dims>; +class RankedI64ElementsAttr dims> : + RankedSignlessIntElementsAttr<64, dims>; class FloatElementsAttr : ElementsAttrBase< CPred<"$_self.isa() &&" @@ -1317,6 +1409,14 @@ CPred<"$_self.cast().getInt() <= " # n>, "whose maximum value is " # n>; +def IntNonNegative : AttrConstraint< + CPred<"!$_self.cast().getValue().isNegative()">, + "whose value is non-negative">; + +def IntPositive : AttrConstraint< + CPred<"$_self.cast().getValue().isStrictlyPositive()">, + "whose value is positive">; + class ArrayMinCount : AttrConstraint< CPred<"$_self.cast().size() >= " # n>, "with at least " # n # " elements">; diff --git a/mlir/test/Dialect/LLVMIR/global.mlir b/mlir/test/Dialect/LLVMIR/global.mlir --- a/mlir/test/Dialect/LLVMIR/global.mlir +++ b/mlir/test/Dialect/LLVMIR/global.mlir @@ -74,12 +74,12 @@ // ----- -// expected-error @+1 {{'addr_space' failed to satisfy constraint: non-negative 32-bit integer}} +// expected-error @+1 {{'addr_space' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative}} "llvm.mlir.global"() {sym_name = "foo", type = !llvm.i64, value = 42 : i64, addr_space = -1 : i32, linkage = 0} : () -> () // ----- -// expected-error @+1 {{'addr_space' failed to satisfy constraint: non-negative 32-bit integer}} +// expected-error @+1 {{'addr_space' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative}} "llvm.mlir.global"() {sym_name = "foo", type = !llvm.i64, value = 42 : i64, addr_space = 1.0 : f32, linkage = 0} : () -> () // ----- diff --git a/mlir/test/Dialect/Loops/invalid.mlir b/mlir/test/Dialect/Loops/invalid.mlir --- a/mlir/test/Dialect/Loops/invalid.mlir +++ b/mlir/test/Dialect/Loops/invalid.mlir @@ -76,7 +76,7 @@ // ----- func @loop_if_not_i1(%arg0: index) { - // expected-error@+1 {{operand #0 must be 1-bit integer}} + // expected-error@+1 {{operand #0 must be 1-bit signless integer}} "loop.if"(%arg0) : (index) -> () return } diff --git a/mlir/test/Dialect/SPIRV/ops.mlir b/mlir/test/Dialect/SPIRV/ops.mlir --- a/mlir/test/Dialect/SPIRV/ops.mlir +++ b/mlir/test/Dialect/SPIRV/ops.mlir @@ -752,7 +752,7 @@ func @logicalUnary(%arg0 : i32) { - // expected-error @+1 {{'spv.LogicalNot' op operand #0 must be 1-bit integer or vector of 1-bit integer values of length 2/3/4, but got 'i32'}} + // expected-error @+1 {{operand #0 must be 1-bit signless integer or vector of 1-bit signless integer values of length 2/3/4, but got 'i32'}} %0 = spv.LogicalNot %arg0 : i32 return } diff --git a/mlir/test/IR/attribute.mlir b/mlir/test/IR/attribute.mlir --- a/mlir/test/IR/attribute.mlir +++ b/mlir/test/IR/attribute.mlir @@ -1,5 +1,74 @@ // RUN: mlir-opt %s -split-input-file -verify-diagnostics | FileCheck %s +//===----------------------------------------------------------------------===// +// Test integer attributes +//===----------------------------------------------------------------------===// + +func @int_attrs_pass() { + "test.int_attrs"() { + // CHECK: any_i32_attr = 5 : ui32 + any_i32_attr = 5 : ui32, + // CHECK-SAME: si32_attr = 7 : si32 + si32_attr = 7 : si32, + // CHECK-SAME: ui32_attr = 6 : ui32 + ui32_attr = 6 : ui32 + } : () -> () + + "test.int_attrs"() { + // CHECK: any_i32_attr = 5 : si32 + any_i32_attr = 5 : si32, + si32_attr = 7 : si32, + ui32_attr = 6 : ui32 + } : () -> () + + "test.int_attrs"() { + // CHECK: any_i32_attr = 5 : i32 + any_i32_attr = 5 : i32, + si32_attr = 7 : si32, + ui32_attr = 6 : ui32 + } : () -> () + + return +} + +// ----- + +func @wrong_int_attrs_signedness_fail() { + // expected-error @+1 {{'si32_attr' failed to satisfy constraint: 32-bit signed integer attribute}} + "test.int_attrs"() { + any_i32_attr = 5 : i32, + si32_attr = 7 : ui32, + ui32_attr = 6 : ui32 + } : () -> () + return +} + +// ----- + +func @wrong_int_attrs_signedness_fail() { + // expected-error @+1 {{'ui32_attr' failed to satisfy constraint: 32-bit unsigned integer attribute}} + "test.int_attrs"() { + any_i32_attr = 5 : i32, + si32_attr = 7 : si32, + ui32_attr = 6 : si32 + } : () -> () + return +} + +// ----- + +func @wrong_int_attrs_type_fail() { + // expected-error @+1 {{'any_i32_attr' failed to satisfy constraint: 32-bit integer attribute}} + "test.int_attrs"() { + any_i32_attr = 5.0 : f32, + si32_attr = 7 : si32, + ui32_attr = 6 : ui32 + } : () -> () + return +} + +// ----- + //===----------------------------------------------------------------------===// // Test Non-negative Int Attr //===----------------------------------------------------------------------===// @@ -15,7 +84,7 @@ // ----- func @negative_int_attr_fail() { - // expected-error @+1 {{'i32attr' failed to satisfy constraint: non-negative 32-bit integer attribute}} + // expected-error @+1 {{'i32attr' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative}} "test.non_negative_int_attr"() {i32attr = -5 : i32, i64attr = 10 : i64} : () -> () return } @@ -23,7 +92,7 @@ // ----- func @negative_int_attr_fail() { - // expected-error @+1 {{'i64attr' failed to satisfy constraint: non-negative 64-bit integer attribute}} + // expected-error @+1 {{'i64attr' failed to satisfy constraint: 64-bit signless integer attribute whose value is non-negative}} "test.non_negative_int_attr"() {i32attr = 5 : i32, i64attr = -10 : i64} : () -> () return } @@ -43,7 +112,7 @@ // ----- func @positive_int_attr_fail() { - // expected-error @+1 {{'i32attr' failed to satisfy constraint: positive 32-bit integer attribute}} + // expected-error @+1 {{'i32attr' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive}} "test.positive_int_attr"() {i32attr = 0 : i32, i64attr = 5: i64} : () -> () return } @@ -51,7 +120,7 @@ // ----- func @positive_int_attr_fail() { - // expected-error @+1 {{'i64attr' failed to satisfy constraint: positive 64-bit integer attribute}} + // expected-error @+1 {{'i64attr' failed to satisfy constraint: 64-bit signless integer attribute whose value is positive}} "test.positive_int_attr"() {i32attr = 5 : i32, i64attr = 0: i64} : () -> () return } @@ -59,7 +128,7 @@ // ----- func @positive_int_attr_fail() { - // expected-error @+1 {{'i32attr' failed to satisfy constraint: positive 32-bit integer attribute}} + // expected-error @+1 {{'i32attr' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive}} "test.positive_int_attr"() {i32attr = -10 : i32, i64attr = 5 : i64} : () -> () return } @@ -67,7 +136,7 @@ // ----- func @positive_int_attr_fail() { - // expected-error @+1 {{'i64attr' failed to satisfy constraint: positive 64-bit integer attribute}} + // expected-error @+1 {{'i64attr' failed to satisfy constraint: 64-bit signless integer attribute whose value is positive}} "test.positive_int_attr"() {i32attr = 5 : i32, i64attr = -10 : i64} : () -> () return } @@ -146,7 +215,7 @@ // ----- func @disallowed_case7_fail() { - // expected-error @+1 {{allowed 32-bit integer cases: 5, 10}} + // expected-error @+1 {{allowed 32-bit signless integer cases: 5, 10}} %0 = "test.i32_enum_attr"() {attr = 7: i32} : () -> i32 return } @@ -154,7 +223,7 @@ // ----- func @disallowed_case7_fail() { - // expected-error @+1 {{allowed 32-bit integer cases: 5, 10}} + // expected-error @+1 {{allowed 32-bit signless integer cases: 5, 10}} %0 = "test.i32_enum_attr"() {attr = 5: i64} : () -> i32 return } @@ -177,7 +246,7 @@ // ----- func @disallowed_case7_fail() { - // expected-error @+1 {{allowed 64-bit integer cases: 5, 10}} + // expected-error @+1 {{allowed 64-bit signless integer cases: 5, 10}} %0 = "test.i64_enum_attr"() {attr = 7: i64} : () -> i32 return } @@ -185,7 +254,7 @@ // ----- func @disallowed_case7_fail() { - // expected-error @+1 {{allowed 64-bit integer cases: 5, 10}} + // expected-error @+1 {{allowed 64-bit signless integer cases: 5, 10}} %0 = "test.i64_enum_attr"() {attr = 5: i32} : () -> i32 return } @@ -250,8 +319,58 @@ // Test IntElementsAttr //===----------------------------------------------------------------------===// -func @correct_type_pass() { +func @correct_int_elements_attr_pass() { "test.int_elements_attr"() { + // CHECK: any_i32_attr = dense<5> : tensor<1x2x3x4xui32>, + any_i32_attr = dense<5> : tensor<1x2x3x4xui32>, + i32_attr = dense<5> : tensor<6xi32> + } : () -> () + + "test.int_elements_attr"() { + // CHECK: any_i32_attr = dense<5> : tensor<1x2x3x4xsi32>, + any_i32_attr = dense<5> : tensor<1x2x3x4xsi32>, + i32_attr = dense<5> : tensor<6xi32> + } : () -> () + + "test.int_elements_attr"() { + // CHECK: any_i32_attr = dense<5> : tensor<1x2x3x4xi32>, + any_i32_attr = dense<5> : tensor<1x2x3x4xi32>, + i32_attr = dense<5> : tensor<6xi32> + } : () -> () + + return +} + +// ----- + +func @wrong_int_elements_attr_type_fail() { + // expected-error @+1 {{'any_i32_attr' failed to satisfy constraint: 32-bit integer elements attribute}} + "test.int_elements_attr"() { + any_i32_attr = dense<5.0> : tensor<1x2x3x4xf32>, + i32_attr = dense<5> : tensor<6xi32> + } : () -> () + return +} + +// ----- + +func @wrong_int_elements_attr_signedness_fail() { + // expected-error @+1 {{'i32_attr' failed to satisfy constraint: 32-bit signless integer elements attribute}} + "test.int_elements_attr"() { + any_i32_attr = dense<5> : tensor<1x2x3x4xi32>, + i32_attr = dense<5> : tensor<6xsi32> + } : () -> () + return +} + +// ----- + +//===----------------------------------------------------------------------===// +// Test Ranked IntElementsAttr +//===----------------------------------------------------------------------===// + +func @correct_type_pass() { + "test.ranked_int_elements_attr"() { // CHECK: matrix_i64_attr = dense<6> : tensor<4x8xi64> // CHECK: vector_i32_attr = dense<5> : tensor<2xi32> matrix_i64_attr = dense<6> : tensor<4x8xi64>, @@ -263,8 +382,8 @@ // ----- func @wrong_element_type_fail() { - // expected-error @+1 {{failed to satisfy constraint: 32-bit int elements attribute of shape [2]}} - "test.int_elements_attr"() { + // expected-error @+1 {{failed to satisfy constraint: 32-bit signless int elements attribute of shape [2]}} + "test.ranked_int_elements_attr"() { matrix_i64_attr = dense<6> : tensor<4x8xi64>, vector_i32_attr = dense<5> : tensor<2xi64> } : () -> () @@ -274,8 +393,8 @@ // ----- func @wrong_shape_fail() { - // expected-error @+1 {{failed to satisfy constraint: 64-bit int elements attribute of shape [4, 8]}} - "test.int_elements_attr"() { + // expected-error @+1 {{failed to satisfy constraint: 64-bit signless int elements attribute of shape [4, 8]}} + "test.ranked_int_elements_attr"() { matrix_i64_attr = dense<6> : tensor<4xi64>, vector_i32_attr = dense<5> : tensor<2xi32> } : () -> () @@ -285,8 +404,8 @@ // ----- func @wrong_shape_fail() { - // expected-error @+1 {{failed to satisfy constraint: 32-bit int elements attribute of shape [2]}} - "test.int_elements_attr"() { + // expected-error @+1 {{failed to satisfy constraint: 32-bit signless int elements attribute of shape [2]}} + "test.ranked_int_elements_attr"() { matrix_i64_attr = dense<6> : tensor<4x8xi64>, vector_i32_attr = dense<5> : tensor } : () -> () diff --git a/mlir/test/IR/invalid-ops.mlir b/mlir/test/IR/invalid-ops.mlir --- a/mlir/test/IR/invalid-ops.mlir +++ b/mlir/test/IR/invalid-ops.mlir @@ -186,7 +186,7 @@ func @func_with_ops(f32) { ^bb0(%a : f32): - // expected-error@+1 {{'std.addi' op operand #0 must be integer-like}} + // expected-error@+1 {{'std.addi' op operand #0 must be signless-integer-like}} %sf = addi %a, %a : f32 } @@ -201,7 +201,7 @@ func @func_with_ops(i32) { ^bb0(%a : i32): - // expected-error@+1 {{failed to satisfy constraint: allowed 64-bit integer cases: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}} + // expected-error@+1 {{failed to satisfy constraint: allowed 64-bit signless integer cases: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}} %r = "std.cmpi"(%a, %a) {predicate = 42} : (i32, i32) -> i1 } @@ -226,7 +226,7 @@ // Integer comparisons are not recognized for float types. func @func_with_ops(f32, f32) { ^bb0(%a : f32, %b : f32): - %r = cmpi "eq", %a, %b : f32 // expected-error {{'lhs' must be integer-like, but got 'f32'}} + %r = cmpi "eq", %a, %b : f32 // expected-error {{'lhs' must be signless-integer-like, but got 'f32'}} } // ----- @@ -298,13 +298,13 @@ // ----- func @invalid_select_shape(%cond : i1, %idx : () -> ()) { - // expected-error@+1 {{'result' must be integer-like or floating-point-like, but got '() -> ()'}} + // expected-error@+1 {{'result' must be signless-integer-like or floating-point-like, but got '() -> ()'}} %sel = select %cond, %idx, %idx : () -> () // ----- func @invalid_cmp_shape(%idx : () -> ()) { - // expected-error@+1 {{'lhs' must be integer-like, but got '() -> ()'}} + // expected-error@+1 {{'lhs' must be signless-integer-like, but got '() -> ()'}} %cmp = cmpi "eq", %idx, %idx : () -> () // ----- @@ -827,7 +827,7 @@ func @invalid_view(%arg0 : index, %arg1 : index, %arg2 : index) { %0 = alloc() : memref<2048xf32> - // expected-error@+1 {{must be 1D memref of 8-bit integer values}} + // expected-error@+1 {{must be 1D memref of 8-bit signless integer values}} %1 = view %0[][%arg0, %arg1] : memref<2048xf32> to memref (d0 * 4 + d1 + s0)>> return @@ -1091,7 +1091,7 @@ func @invalid_prefetch_locality_hint(%i : index) { %0 = alloc() : memref<10xf32> - // expected-error@+1 {{32-bit integer attribute whose minimum value is 0 whose maximum value is 3}} + // expected-error@+1 {{32-bit signless integer attribute whose minimum value is 0 whose maximum value is 3}} prefetch %0[%i], read, locality<5>, data : memref<10xf32> return } @@ -1154,7 +1154,7 @@ // 0 alignment value. func @assume_alignment(%0: memref<4x4xf16>) { - // expected-error@+1 {{'std.assume_alignment' op attribute 'alignment' failed to satisfy constraint: positive 32-bit integer attribute}} + // expected-error@+1 {{'std.assume_alignment' op attribute 'alignment' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive}} std.assume_alignment %0, 0 : memref<4x4xf16> return } diff --git a/mlir/test/lib/TestDialect/TestOps.td b/mlir/test/lib/TestDialect/TestOps.td --- a/mlir/test/lib/TestDialect/TestOps.td +++ b/mlir/test/lib/TestDialect/TestOps.td @@ -26,6 +26,14 @@ // Test Types //===----------------------------------------------------------------------===// +def IntTypesOp : TEST_Op<"int_types"> { + let results = (outs + AnyI16:$any_i16, + SI32:$si32, + UI64:$ui64 + ); +} + def ComplexF64 : Complex; def ComplexOp : TEST_Op<"complex_f64"> { let results = (outs ComplexF64); @@ -127,15 +135,15 @@ def NonNegIntAttrOp : TEST_Op<"non_negative_int_attr"> { let arguments = (ins - NonNegativeI32Attr:$i32attr, - NonNegativeI64Attr:$i64attr + Confined:$i32attr, + Confined:$i64attr ); } def PositiveIntAttrOp : TEST_Op<"positive_int_attr"> { let arguments = (ins - PositiveI32Attr:$i32attr, - PositiveI64Attr:$i64attr + Confined:$i32attr, + Confined:$i64attr ); } @@ -187,6 +195,15 @@ let results = (outs I32:$val); } + +def IntAttrOp : TEST_Op<"int_attrs"> { + let arguments = (ins + AnyI32Attr:$any_i32_attr, + UI32Attr:$ui32_attr, + SI32Attr:$si32_attr + ); +} + def FloatElementsAttrOp : TEST_Op<"float_elements_attr"> { let arguments = (ins RankedF32ElementsAttr<[2]>:$scalar_f32_attr, @@ -205,6 +222,13 @@ $f64attr)>; def IntElementsAttrOp : TEST_Op<"int_elements_attr"> { + let arguments = (ins + AnyI32ElementsAttr:$any_i32_attr, + I32ElementsAttr:$i32_attr + ); +} + +def RankedIntElementsAttrOp : TEST_Op<"ranked_int_elements_attr"> { let arguments = (ins RankedI32ElementsAttr<[2]>:$vector_i32_attr, RankedI64ElementsAttr<[4, 8]>:$matrix_i64_attr diff --git a/mlir/test/mlir-tblgen/predicate.td b/mlir/test/mlir-tblgen/predicate.td --- a/mlir/test/mlir-tblgen/predicate.td +++ b/mlir/test/mlir-tblgen/predicate.td @@ -33,7 +33,7 @@ // CHECK-LABEL: OpF::verify() // CHECK: (tblgen_attr.cast().getInt() >= 10) -// CHECK-SAME: return emitOpError("attribute 'attr' failed to satisfy constraint: 32-bit integer attribute whose minimum value is 10"); +// CHECK-SAME: return emitOpError("attribute 'attr' failed to satisfy constraint: 32-bit signless integer attribute whose minimum value is 10"); def OpFX : NS_Op<"op_for_int_max_val", []> { let arguments = (ins Confined]>:$attr); @@ -41,7 +41,7 @@ // CHECK-LABEL: OpFX::verify() // CHECK: (tblgen_attr.cast().getInt() <= 10) -// CHECK-SAME: return emitOpError("attribute 'attr' failed to satisfy constraint: 32-bit integer attribute whose maximum value is 10"); +// CHECK-SAME: return emitOpError("attribute 'attr' failed to satisfy constraint: 32-bit signless integer attribute whose maximum value is 10"); def OpG : NS_Op<"op_for_arr_min_count", []> { let arguments = (ins Confined]>:$attr); diff --git a/mlir/test/mlir-tblgen/types.mlir b/mlir/test/mlir-tblgen/types.mlir --- a/mlir/test/mlir-tblgen/types.mlir +++ b/mlir/test/mlir-tblgen/types.mlir @@ -1,5 +1,36 @@ // RUN: mlir-opt %s -split-input-file -verify-diagnostics | FileCheck %s +func @correct_int_types_success() { + "test.int_types"() : () -> (i16, si32, ui64) + "test.int_types"() : () -> (si16, si32, ui64) + "test.int_types"() : () -> (ui16, si32, ui64) + return +} + +// ----- + +func @wrong_int_type_signedness_failure() { + // expected-error @+1 {{result #1 must be 32-bit signed integer, but got 'ui32'}} + "test.int_types"() : () -> (ui16, ui32, ui64) + return +} + +// ----- + +func @wrong_int_type_signedness_failure() { + // expected-error @+1 {{result #2 must be 64-bit unsigned integer, but got 'si64'}} + "test.int_types"() : () -> (ui16, si32, si64) + return +} + +// ----- + +func @wrong_int_type_failure() { + // expected-error @+1 {{result #0 must be 16-bit integer, but got 'f16'}} + "test.int_types"() : () -> (f16, si32, ui64) + return +} + // ----- // CHECK-LABEL: @complex_f64_success @@ -50,7 +81,7 @@ // ----- func @tuple_wrong_type_scalar() { - // expected-error@+1 {{must be tuple with any combination of 32-bit integer or 32-bit float values}} + // expected-error@+1 {{must be tuple with any combination of 32-bit signless integer or 32-bit float values}} "test.tuple_32_bit"() : () -> (tuple) return } @@ -58,7 +89,7 @@ // ----- func @tuple_wrong_type_tensor() { - // expected-error@+1 {{must be tuple with any combination of 32-bit integer or 32-bit float values}} + // expected-error@+1 {{must be tuple with any combination of 32-bit signless integer or 32-bit float values}} "test.tuple_32_bit"() : () -> (tuple>) return } @@ -98,7 +129,7 @@ // ----- func @nested_tuple_multi_level_wrong_type() { - // expected-error@+1 {{must be nested tuple with any combination of 32-bit integer or 32-bit float values}} + // expected-error@+1 {{must be nested tuple with any combination of 32-bit signless integer or 32-bit float values}} "test.nested_tuple_32_bit"() : () -> (tuple>>) return } @@ -117,7 +148,7 @@ // ----- func @rank_less_than_2_I8_F32_memref_bad_type() { - // expected-error@+1 {{must be 0D/1D memref of 8-bit integer or 32-bit float values}} + // expected-error@+1 {{must be 0D/1D memref of 8-bit signless integer or 32-bit float values}} "test.rank_less_than_2_I8_F32_memref"() : () -> (memref) return } @@ -125,7 +156,7 @@ // ----- func @rank_less_than_2_I8_F32_memref_bad_rank() { - // expected-error@+1 {{must be 0D/1D memref of 8-bit integer or 32-bit float values}} + // expected-error@+1 {{must be 0D/1D memref of 8-bit signless integer or 32-bit float values}} "test.rank_less_than_2_I8_F32_memref"() : () -> (memref<1x2xi8>) return } @@ -148,7 +179,7 @@ // ----- func @nd_tensor_of_success_wrong_type_4d(%arg0: tensor, %arg1: tensor<10xf32>, %arg2: tensor<20x30xi16>, %arg3: tensor<40x50x60xi16>, %arg4: tensor<70x80x90x100xi32>) { - // expected-error @+1 {{'test.nd_tensor_of' op operand #4 must be 4D tensor of 16-bit integer values}} + // expected-error @+1 {{'test.nd_tensor_of' op operand #4 must be 4D tensor of 16-bit signless integer values}} "test.nd_tensor_of"(%arg0, %arg1, %arg2, %arg3, %arg3) : (tensor, tensor<10xf32>, tensor<20x30xi16>, tensor<40x50x60xi16>, tensor<40x50x60xi16>) -> () return } @@ -193,7 +224,7 @@ // ----- func @multi_tensor_rank_of_wrong_unranked_type(%arg0: tensor<2x2xi8>) { - // expected-error @+1 {{'test.multi_tensor_rank_of' op operand #0 must be 0D/1D tensor of 8-bit integer or 32-bit integer or 32-bit float values}} + // expected-error @+1 {{'test.multi_tensor_rank_of' op operand #0 must be 0D/1D tensor of 8-bit signless integer or 32-bit signless integer or 32-bit float values}} "test.multi_tensor_rank_of"(%arg0) : (tensor<2x2xi8>) -> () return } @@ -201,7 +232,7 @@ // ----- func @multi_tensor_rank_of_wrong_element_type(%arg0: tensor<2xi16>) { - // expected-error @+1 {{'test.multi_tensor_rank_of' op operand #0 must be 0D/1D tensor of 8-bit integer or 32-bit integer or 32-bit float values}} + // expected-error @+1 {{'test.multi_tensor_rank_of' op operand #0 must be 0D/1D tensor of 8-bit signless integer or 32-bit signless integer or 32-bit float values}} "test.multi_tensor_rank_of"(%arg0) : (tensor<2xi16>) -> () return } @@ -218,7 +249,7 @@ // ----- func @fixed_element_types(%arg0: tensor<* x i32>, %arg1: tensor<* x f32>) { - // expected-error@+1 {{'res' is 16-bit integer}} + // expected-error@+1 {{'res' is 16-bit signless integer}} "test.arg_and_res_have_fixed_element_types"(%arg0, %arg1) : (tensor<* x i32>, tensor<* x f32>) -> tensor<* x i32> return } @@ -430,7 +461,7 @@ // ----- func @elements_attr_not_i32_f32() { - // expected-error@+1 {{32-bit integer elements attribute}} + // expected-error@+1 {{32-bit signless integer elements attribute}} "test.i32ElementsAttr"() {attr = dense<[1.0, 20.0]>:tensor<2xf32>} : () -> () return } @@ -438,7 +469,7 @@ // ----- func @elements_attr_not_i32_i64() { - // expected-error@+1 {{32-bit integer elements attribute}} + // expected-error@+1 {{32-bit signless integer elements attribute}} "test.i32ElementsAttr"() {attr = dense<[1, 20]>:tensor<2xi64>} : () -> () return }