[Mlir-commits] [mlir] 5b2cc6c - [mlir][ods] Improve integer signedness modelling

Lei Zhang llvmlistbot at llvm.org
Wed Mar 4 12:07:07 PST 2020


Author: Lei Zhang
Date: 2020-03-04T15:05:42-05:00
New Revision: 5b2cc6c3d0024d0d05e881d74d63be0ea2dca546

URL: https://github.com/llvm/llvm-project/commit/5b2cc6c3d0024d0d05e881d74d63be0ea2dca546
DIFF: https://github.com/llvm/llvm-project/commit/5b2cc6c3d0024d0d05e881d74d63be0ea2dca546.diff

LOG: [mlir][ods] Improve integer signedness modelling

A previous commit added support for integer signedness in C++
IntegerType. This change introduces ODS definitions for
integer types and integer (element) attributes w.r.t. signedness.

This commit also updates various existing definitions' descriptions
to mention signless where suitable to make it more clear.

Positive and non-negative integer attributes are removed to avoid
the explosion of subclasses. Instead, one should use more atmoic
constraints together with Confined to model that. For example,
`Confined<..., [IntPositive]>`.

Differential Revision: https://reviews.llvm.org/D75610

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
    mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td
    mlir/include/mlir/Dialect/StandardOps/IR/Ops.td
    mlir/include/mlir/IR/OpBase.td
    mlir/test/Dialect/LLVMIR/global.mlir
    mlir/test/Dialect/Loops/invalid.mlir
    mlir/test/Dialect/SPIRV/ops.mlir
    mlir/test/IR/attribute.mlir
    mlir/test/IR/invalid-ops.mlir
    mlir/test/lib/TestDialect/TestOps.td
    mlir/test/mlir-tblgen/predicate.td
    mlir/test/mlir-tblgen/types.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 66d5f9d3c82c..b4585407edce 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -565,11 +565,15 @@ def LLVM_AddressOfOp
 def LLVM_GlobalOp
     : LLVM_ZeroResultOp<"mlir.global",
                         [IsolatedFromAbove,
-                         SingleBlockImplicitTerminator<"ReturnOp">, Symbol]>,
-      Arguments<(ins TypeAttr:$type, UnitAttr:$constant, StrAttr:$sym_name,
-                 Linkage:$linkage,
-                 OptionalAttr<AnyAttr>:$value,
-                 DefaultValuedAttr<NonNegativeI32Attr, "0">:$addr_space)> {
+                         SingleBlockImplicitTerminator<"ReturnOp">, Symbol]> {
+  let arguments = (ins
+    TypeAttr:$type,
+    UnitAttr:$constant,
+    StrAttr:$sym_name,
+    Linkage:$linkage,
+    OptionalAttr<AnyAttr>:$value,
+    DefaultValuedAttr<Confined<I32Attr, [IntNonNegative]>, "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
index 2dbee404423c..65bdd1ef3022 100644
--- a/mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td
+++ b/mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td
@@ -63,7 +63,7 @@ class SPV_BitEnumAttr<string name, string description,
                       list<BitEnumAttrCase> cases> :
     BitEnumAttr<name, description, cases> {
   let predicate = And<[
-    IntegerAttrBase<I32, "">.predicate,
+    I32Attr.predicate,
     SPV_IsKnownEnumCaseFor<name>,
   ]>;
   let cppNamespace = "::mlir::spirv";
@@ -74,7 +74,7 @@ class SPV_I32EnumAttr<string name, string description,
                       list<I32EnumAttrCase> cases> :
     I32EnumAttr<name, description, cases> {
   let predicate = And<[
-    IntegerAttrBase<I32, "">.predicate,
+    I32Attr.predicate,
     SPV_IsKnownEnumCaseFor<name>,
   ]>;
   let cppNamespace = "::mlir::spirv";
@@ -2955,7 +2955,7 @@ def SPV_IsStructType : CPred<"$_self.isa<::mlir::spirv::StructType>()">;
 
 def SPV_Void : TypeAlias<NoneType, "void type">;
 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
index a9217b30bd28..2fe0365408e2 100644
--- a/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td
+++ b/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td
@@ -253,7 +253,8 @@ def AssumeAlignmentOp : Std_Op<"assume_alignment"> {
     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<I32Attr, [IntPositive]>:$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
index d431d4ebabf4..2bc654628aba 100644
--- a/mlir/include/mlir/IR/OpBase.td
+++ b/mlir/include/mlir/IR/OpBase.td
@@ -313,25 +313,41 @@ class AnyTypeOf<list<Type> allowedTypes, string description = ""> : Type<
         description)>;
 
 // Integer types.
-// Any integer type irrespective of its width.
-def AnySignlessInteger : Type<
-  CPred<"$_self.isSignlessInteger()">, "integer">;
 
-// Index type.
-def Index : Type<CPred<"$_self.isa<IndexType>()">, "index">,
-            BuildableType<"$_builder.getIndexType()">;
+// Any integer type irrespective of its width and signedness semantics.
+def AnyInteger : Type<CPred<"$_self.isInteger()">, "integer">;
+
+// Any integer type (regardless of signedness semantics) of a specific width.
+class AnyI<int width>
+    : Type<CPred<"$_self.isInteger(" # width # ")">, width # "-bit integer"> {
+  int bitwidth = width;
+}
 
-// Integer type of a specific width.
+class AnyIntOfWidths<list<int> widths> :
+    AnyTypeOf<!foreach(w, widths, AnyI<w>),
+              StrJoinInt<widths, "/">.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<int width>
     : Type<CPred<"$_self.isSignlessInteger(" # width # ")">,
-                  width # "-bit integer">,
+                  width # "-bit signless integer">,
       BuildableType<"$_builder.getIntegerType(" # width # ")"> {
   int bitwidth = width;
 }
 
-class IntOfWidths<list<int> widths> :
+class SignlessIntOfWidths<list<int> widths> :
     AnyTypeOf<!foreach(w, widths, I<w>),
-              StrJoinInt<widths, "/">.result # "-bit integer">;
+              StrJoinInt<widths, "/">.result # "-bit signless integer">;
 
 def I1  : I<1>;
 def I8  : I<8>;
@@ -339,7 +355,29 @@ def I16 : I<16>;
 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<int width>
+    : Type<CPred<"$_self.isSignedInteger(" # width # ")">,
+                  width # "-bit signed integer">,
+      BuildableType<
+        "$_builder.getIntegerType(" # width # ", /*isSigned=*/true)"> {
+  int bitwidth = width;
+}
+
+class SignedIntOfWidths<list<int> widths> :
+    AnyTypeOf<!foreach(w, widths, SI<w>),
+              StrJoinInt<widths, "/">.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 @@ def AnyUnsignedInteger : Type<
 class UI<int width>
     : Type<CPred<"$_self.isUnsignedInteger(" # width # ")">,
                   width # "-bit unsigned integer">,
-      BuildableType<"$_builder.getIntegerType(" # width #
-                    ", /*isSigned=*/false)"> {
+      BuildableType<
+        "$_builder.getIntegerType(" # width # ", /*isSigned=*/false)"> {
   int bitwidth = width;
 }
 
@@ -363,6 +401,10 @@ def UI16 : UI<16>;
 def UI32 : UI<32>;
 def UI64 : UI<64>;
 
+// Index type.
+def Index : Type<CPred<"$_self.isa<IndexType>()">, "index">,
+            BuildableType<"$_builder.getIndexType()">;
+
 // Floating point types.
 
 // Any float type irrespective of its width.
@@ -613,23 +655,23 @@ def BoolLike : TypeConstraint<Or<[I1.predicate, VectorOf<[I1]>.predicate,
                                   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<Or<[
         AnySignlessInteger.predicate, Index.predicate,
         VectorOf<[AnySignlessInteger]>.predicate,
         TensorOf<[AnySignlessInteger]>.predicate]>,
-    "integer-like">;
+    "signless-integer-like">;
 
 // Type constraint for float-like types: floats, vectors or tensors thereof.
 def FloatLike : TypeConstraint<Or<[AnyFloat.predicate,
         VectorOf<[AnyFloat]>.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<Or<[
     SignlessIntegerLike.predicate, FloatLike.predicate]>,
-    "integer-like or floating-point-like">;
+    "signless-integer-like or floating-point-like">;
 
 
 //===----------------------------------------------------------------------===//
@@ -750,57 +792,91 @@ def BoolAttr : Attr<CPred<"$_self.isa<BoolAttr>()">, "bool attribute"> {
   let constBuilderCall = "$_builder.getBoolAttr($0)";
 }
 
-// Base class for integer attributes of fixed width.
-class IntegerAttrBase<I attrValType, string descr> :
+// Base class for any integer (regardless of signedness semantics) attributes
+// of fixed width.
+class AnyIntegerAttrBase<AnyI attrValType, string descr> :
     TypedAttrBase<
       attrValType, "IntegerAttr",
       And<[CPred<"$_self.isa<IntegerAttr>()">,
            CPred<"$_self.cast<IntegerAttr>().getType()."
-                 "isSignlessInteger(" # attrValType.bitwidth # ")">]>,
+                 "isInteger(" # attrValType.bitwidth # ")">]>,
       descr> {
   let returnType = [{ APInt }];
+  let constBuilderCall = ?;
 }
 
+def AnyI1Attr  : AnyIntegerAttrBase<AnyI1,  "1-bit integer attribute">;
+def AnyI8Attr  : AnyIntegerAttrBase<AnyI8,  "8-bit integer attribute">;
+def AnyI16Attr : AnyIntegerAttrBase<AnyI16, "16-bit integer attribute">;
+def AnyI32Attr : AnyIntegerAttrBase<AnyI32, "32-bit integer attribute">;
+def AnyI64Attr : AnyIntegerAttrBase<AnyI64, "64-bit integer attribute">;
+
 def APIntAttr : Attr<CPred<"$_self.isa<IntegerAttr>()">,
                      "arbitrary integer attribute"> {
   let storageType = [{ IntegerAttr }];
   let returnType = [{ APInt }];
 }
 
-def I1Attr  : IntegerAttrBase<I1,  "1-bit integer attribute">;
-def I8Attr  : IntegerAttrBase<I8,  "8-bit integer attribute">;
-def I16Attr : IntegerAttrBase<I16, "16-bit integer attribute">;
-def I32Attr : IntegerAttrBase<I32, "32-bit integer attribute">;
-def I64Attr : IntegerAttrBase<I64, "64-bit integer attribute">;
+// Base class for signless integer attributes of fixed width.
+class SignlessIntegerAttrBase<I attrValType, string descr> :
+    TypedAttrBase<
+      attrValType, "IntegerAttr",
+      And<[CPred<"$_self.isa<IntegerAttr>()">,
+           CPred<"$_self.cast<IntegerAttr>().getType()."
+                 "isSignlessInteger(" # attrValType.bitwidth # ")">]>,
+      descr> {
+  let returnType = [{ APInt }];
+}
+
+def I1Attr  : SignlessIntegerAttrBase<I1,  "1-bit signless integer attribute">;
+def I8Attr  : SignlessIntegerAttrBase<I8,  "8-bit signless integer attribute">;
+def I16Attr : SignlessIntegerAttrBase<I16, "16-bit signless integer attribute">;
+def I32Attr : SignlessIntegerAttrBase<I32, "32-bit signless integer attribute">;
+def I64Attr : SignlessIntegerAttrBase<I64, "64-bit signless integer attribute">;
 
-class NonNegativeIntAttrBase<I attrValType, string descr> :
+// Base class for signed integer attributes of fixed width.
+class SignedIntegerAttrBase<SI attrValType, string descr> :
     TypedAttrBase<
       attrValType, "IntegerAttr",
-      And<[IntegerAttrBase<attrValType, "">.predicate,
-           CPred<"!$_self.cast<IntegerAttr>().getValue().isNegative()">]>,
+      And<[CPred<"$_self.isa<IntegerAttr>()">,
+           CPred<"$_self.cast<IntegerAttr>().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<I attrValType, string descr> :
+// Base class for unsigned integer attributes of fixed width.
+class UnsignedIntegerAttrBase<UI attrValType, string descr> :
     TypedAttrBase<
       attrValType, "IntegerAttr",
-      And<[IntegerAttrBase<attrValType, "">.predicate,
-           CPred<"$_self.cast<IntegerAttr>().getValue()"
-                 ".isStrictlyPositive()">]>,
+      And<[CPred<"$_self.isa<IntegerAttr>()">,
+           CPred<"$_self.cast<IntegerAttr>().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<F attrValType, string descr> :
@@ -879,7 +955,7 @@ class StrEnumAttrCase<string sym, int val = -1> :
 // its representation as a string and a C++ symbol name which may be 
diff erent.
 class IntEnumAttrCaseBase<I intType, string sym, string strVal, int intVal> :
     EnumAttrCaseInfo<sym, intVal, strVal>,
-    IntegerAttrBase<intType, "case " # strVal> {
+    SignlessIntegerAttrBase<intType, "case " # strVal> {
   let predicate =
     CPred<"$_self.cast<IntegerAttr>().getInt() == " # intVal>;
 }
@@ -896,7 +972,7 @@ class I64EnumAttrCase<string sym, int val, string str = sym>
 // one bit set.
 class BitEnumAttrCase<string sym, int val> :
     EnumAttrCaseInfo<sym, val, sym>,
-    IntegerAttrBase<I32, "case " # sym> {
+    SignlessIntegerAttrBase<I32, "case " # sym> {
   let predicate = CPred<
     "$_self.cast<IntegerAttr>().getValue().getZExtValue() & " # val # "u">;
 }
@@ -982,11 +1058,11 @@ class StrEnumAttr<string name, string description,
 class IntEnumAttr<I intType, string name, string description,
                   list<IntEnumAttrCaseBase> cases> :
     EnumAttrInfo<name, cases>,
-    IntegerAttrBase<intType,
+    SignlessIntegerAttrBase<intType,
       !if(!empty(description), "allowed " # intType.description # " cases: " #
           StrJoinInt<!foreach(case, cases, case.value)>.result, description)> {
   let predicate = And<[
-    IntegerAttrBase<intType, "">.predicate,
+    SignlessIntegerAttrBase<intType, "">.predicate,
     Or<!foreach(case, cases, case.predicate)>]>;
 }
 
@@ -1015,9 +1091,9 @@ class I64EnumAttr<string name, string description,
 // delimiter to a symbol and vice versa.
 class BitEnumAttr<string name, string description,
                   list<BitEnumAttrCase> cases> :
-    EnumAttrInfo<name, cases>, IntegerAttrBase<I32, description> {
+    EnumAttrInfo<name, cases>, SignlessIntegerAttrBase<I32, description> {
   let predicate = And<[
-    IntegerAttrBase<I32, "">.predicate,
+    I32Attr.predicate,
     // Make sure we don't have unknown bit set.
     CPred<"!($_self.cast<IntegerAttr>().getValue().getZExtValue() & (~(" #
           StrJoin<!foreach(case, cases, case.value # "u"), "|">.result #
@@ -1057,37 +1133,51 @@ class ElementsAttrBase<Pred condition, string description> :
 }
 
 def ElementsAttr : ElementsAttrBase<CPred<"$_self.isa<ElementsAttr>()">,
-                                   "constant vector/tensor attribute">;
-
-class IntElementsAttr<int width> : ElementsAttrBase<
-  CPred<"$_self.isa<DenseIntElementsAttr>() &&"
-      "$_self.cast<DenseIntElementsAttr>().getType()."
-      "getElementType().isSignlessInteger(" # width # ")">,
-  width # "-bit integer elements attribute"> {
+                                    "constant vector/tensor attribute">;
 
+class IntElementsAttrBase<Pred condition, string description> :
+    ElementsAttrBase<And<[CPred<"$_self.isa<DenseIntElementsAttr>()">,
+                          condition]>,
+                     description> {
   let storageType = [{ DenseIntElementsAttr }];
   let returnType = [{ DenseIntElementsAttr }];
 
+  let convertFromStorage = "$_self";
+}
+
+class AnyIntElementsAttr<int width> : IntElementsAttrBase<
+  CPred<"$_self.cast<DenseIntElementsAttr>().getType()."
+        "getElementType().isInteger(" # width # ")">,
+  width # "-bit integer elements attribute">;
+
+def AnyI32ElementsAttr : AnyIntElementsAttr<32>;
+def AnyI64ElementsAttr : AnyIntElementsAttr<64>;
+
+class SignlessIntElementsAttr<int width> : IntElementsAttrBase<
+  CPred<"$_self.cast<DenseIntElementsAttr>().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<DenseIntElementsAttr>()";
-  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<int width, list<int> dims> : IntElementsAttr<width> {
+// A `width`-bit signless integer elements attribute. The attribute should be
+// ranked and has a shape as specified in `dims`.
+class RankedSignlessIntElementsAttr<int width, list<int> dims> :
+    SignlessIntElementsAttr<width> {
   // Check that this has the specified shape.
   let predicate = And<[
-    IntElementsAttr<width>.predicate,
+    SignlessIntElementsAttr<width>.predicate,
     CPred<"$_self.cast<DenseIntElementsAttr>().getType().getShape() == "
         "ArrayRef<int64_t>({" # StrJoinInt<dims>.result # "})">]>;
 
-  let description = width # "-bit int elements attribute of shape [" #
+  let description = width # "-bit signless int elements attribute of shape [" #
                     StrJoinInt<dims>.result # "]";
 
   let constBuilderCall = "DenseIntElementsAttr::get("
@@ -1095,8 +1185,10 @@ class RankedIntElementsAttr<int width, list<int> dims> : IntElementsAttr<width>
     "}, $_builder.getIntegerType(" # width # ")), makeArrayRef($0))";
 }
 
-class RankedI32ElementsAttr<list<int> dims> : RankedIntElementsAttr<32, dims>;
-class RankedI64ElementsAttr<list<int> dims> : RankedIntElementsAttr<64, dims>;
+class RankedI32ElementsAttr<list<int> dims> :
+    RankedSignlessIntElementsAttr<32, dims>;
+class RankedI64ElementsAttr<list<int> dims> :
+    RankedSignlessIntElementsAttr<64, dims>;
 
 class FloatElementsAttr<int width> : ElementsAttrBase<
   CPred<"$_self.isa<DenseFPElementsAttr>() &&"
@@ -1317,6 +1409,14 @@ class IntMaxValue<int n> : AttrConstraint<
     CPred<"$_self.cast<IntegerAttr>().getInt() <= " # n>,
     "whose maximum value is " # n>;
 
+def IntNonNegative : AttrConstraint<
+    CPred<"!$_self.cast<IntegerAttr>().getValue().isNegative()">,
+    "whose value is non-negative">;
+
+def IntPositive : AttrConstraint<
+    CPred<"$_self.cast<IntegerAttr>().getValue().isStrictlyPositive()">,
+    "whose value is positive">;
+
 class ArrayMinCount<int n> : AttrConstraint<
     CPred<"$_self.cast<ArrayAttr>().size() >= " # n>,
     "with at least " # n # " elements">;

diff  --git a/mlir/test/Dialect/LLVMIR/global.mlir b/mlir/test/Dialect/LLVMIR/global.mlir
index 4e7cd285d51f..70944b86960d 100644
--- a/mlir/test/Dialect/LLVMIR/global.mlir
+++ b/mlir/test/Dialect/LLVMIR/global.mlir
@@ -74,12 +74,12 @@ llvm.mlir.global internal constant @constant(37.0) : !llvm<"label">
 
 // -----
 
-// 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
index 9b170275c9f6..44075aca59af 100644
--- a/mlir/test/Dialect/Loops/invalid.mlir
+++ b/mlir/test/Dialect/Loops/invalid.mlir
@@ -76,7 +76,7 @@ func @loop_for_single_index_argument(%arg0: index) {
 // -----
 
 func @loop_if_not_i1(%arg0: index) {
-  // expected-error at +1 {{operand #0 must be 1-bit integer}}
+  // expected-error at +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
index cf7ab6096689..d2f9eba7e4ba 100644
--- a/mlir/test/Dialect/SPIRV/ops.mlir
+++ b/mlir/test/Dialect/SPIRV/ops.mlir
@@ -752,7 +752,7 @@ func @logicalUnary(%arg0 : i1)
 
 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
index c0ee566738e3..50d4e8cd1454 100644
--- 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 @non_negative_int_attr_pass() {
 // -----
 
 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() {
 // -----
 
 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_pass() {
 // -----
 
 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() {
 // -----
 
 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() {
 // -----
 
 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() {
 // -----
 
 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 @allowed_cases_pass() {
 // -----
 
 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() {
 // -----
 
 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 @allowed_cases_pass() {
 // -----
 
 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() {
 // -----
 
 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 @@ func @fn() { return }
 // 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 @correct_type_pass() {
 // -----
 
 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_element_type_fail() {
 // -----
 
 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() {
 // -----
 
 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<i32>
   } : () -> ()

diff  --git a/mlir/test/IR/invalid-ops.mlir b/mlir/test/IR/invalid-ops.mlir
index 07b6b9f4b121..f50bced3d8f6 100644
--- a/mlir/test/IR/invalid-ops.mlir
+++ b/mlir/test/IR/invalid-ops.mlir
@@ -186,7 +186,7 @@ func @func_with_ops(f32) {
 
 func @func_with_ops(f32) {
 ^bb0(%a : f32):
-  // expected-error at +1 {{'std.addi' op operand #0 must be integer-like}}
+  // expected-error at +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) {
 
 func @func_with_ops(i32) {
 ^bb0(%a : i32):
-  // expected-error at +1 {{failed to satisfy constraint: allowed 64-bit integer cases: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}
+  // expected-error at +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 @@ func @func_with_ops(i32, i32) {
 // 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 @func_with_ops(i1, tensor<42xi32>, tensor<?xi32>) {
 // -----
 
 func @invalid_select_shape(%cond : i1, %idx : () -> ()) {
-  // expected-error at +1 {{'result' must be integer-like or floating-point-like, but got '() -> ()'}}
+  // expected-error at +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 at +1 {{'lhs' must be integer-like, but got '() -> ()'}}
+  // expected-error at +1 {{'lhs' must be signless-integer-like, but got '() -> ()'}}
   %cmp = cmpi "eq", %idx, %idx : () -> ()
 
 // -----
@@ -346,7 +346,7 @@ func @invalid_cmp_attr(%idx : i32) {
 // -----
 
 func @cmpf_generic_invalid_predicate_value(%a : f32) {
-  // expected-error at +1 {{attribute 'predicate' failed to satisfy constraint: allowed 64-bit integer cases}}
+  // expected-error at +1 {{attribute 'predicate' failed to satisfy constraint: allowed 64-bit signless integer cases}}
   %r = "std.cmpf"(%a, %a) {predicate = 42} : (f32, f32) -> i1
 }
 
@@ -827,7 +827,7 @@ func @invalid_view(%arg0 : index, %arg1 : index, %arg2 : index) {
 
 func @invalid_view(%arg0 : index, %arg1 : index, %arg2 : index) {
   %0 = alloc() : memref<2048xf32>
-  // expected-error at +1 {{must be 1D memref of 8-bit integer values}}
+  // expected-error at +1 {{must be 1D memref of 8-bit signless integer values}}
   %1 = view %0[][%arg0, %arg1]
     : memref<2048xf32> to memref<?x?xf32, affine_map<(d0, d1)[s0] -> (d0 * 4 + d1 + s0)>>
   return
@@ -1091,7 +1091,7 @@ func @invalid_prefetch_cache_type(%i : index) {
 
 func @invalid_prefetch_locality_hint(%i : index) {
   %0 = alloc() : memref<10xf32>
-  // expected-error at +1 {{32-bit integer attribute whose minimum value is 0 whose maximum value is 3}}
+  // expected-error at +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 @@ func @assume_alignment(%0: memref<4x4xf16>) {
 
 // 0 alignment value.
 func @assume_alignment(%0: memref<4x4xf16>) {
-  // expected-error at +1 {{'std.assume_alignment' op attribute 'alignment' failed to satisfy constraint: positive 32-bit integer attribute}}
+  // expected-error at +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
index 135dcdea6fd9..26205e7eb855 100644
--- a/mlir/test/lib/TestDialect/TestOps.td
+++ b/mlir/test/lib/TestDialect/TestOps.td
@@ -26,6 +26,14 @@ class TEST_Op<string mnemonic, list<OpTrait> traits = []> :
 // Test Types
 //===----------------------------------------------------------------------===//
 
+def IntTypesOp : TEST_Op<"int_types"> {
+  let results = (outs
+    AnyI16:$any_i16,
+    SI32:$si32,
+    UI64:$ui64
+  );
+}
+
 def ComplexF64 : Complex<F64>;
 def ComplexOp : TEST_Op<"complex_f64"> {
   let results = (outs ComplexF64);
@@ -127,15 +135,15 @@ def MixedNormalVariadicResults : TEST_Op<
 
 def NonNegIntAttrOp : TEST_Op<"non_negative_int_attr"> {
   let arguments = (ins
-      NonNegativeI32Attr:$i32attr,
-      NonNegativeI64Attr:$i64attr
+      Confined<I32Attr, [IntNonNegative]>:$i32attr,
+      Confined<I64Attr, [IntNonNegative]>:$i64attr
   );
 }
 
 def PositiveIntAttrOp : TEST_Op<"positive_int_attr"> {
   let arguments = (ins
-      PositiveI32Attr:$i32attr,
-      PositiveI64Attr:$i64attr
+      Confined<I32Attr, [IntPositive]>:$i32attr,
+      Confined<I64Attr, [IntPositive]>:$i64attr
   );
 }
 
@@ -187,6 +195,15 @@ def I64EnumAttrOp : TEST_Op<"i64_enum_attr"> {
   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 @@ def UpdateFloatElementsAttr : Pat<
     $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
index 8ce4913e91d3..c679bd9e9704 100644
--- a/mlir/test/mlir-tblgen/predicate.td
+++ b/mlir/test/mlir-tblgen/predicate.td
@@ -33,7 +33,7 @@ def OpF : NS_Op<"op_for_int_min_val", []> {
 
 // CHECK-LABEL: OpF::verify()
 // CHECK:       (tblgen_attr.cast<IntegerAttr>().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<I32Attr, [IntMaxValue<10>]>:$attr);
@@ -41,7 +41,7 @@ def OpFX : NS_Op<"op_for_int_max_val", []> {
 
 // CHECK-LABEL: OpFX::verify()
 // CHECK:       (tblgen_attr.cast<IntegerAttr>().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<ArrayAttr, [ArrayMinCount<8>]>:$attr);

diff  --git a/mlir/test/mlir-tblgen/types.mlir b/mlir/test/mlir-tblgen/types.mlir
index 8c3cce72f3dc..f498a74f596f 100644
--- 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_empty_success() {
 // -----
 
 func @tuple_wrong_type_scalar() {
-  // expected-error at +1 {{must be tuple with any combination of 32-bit integer or 32-bit float values}}
+  // expected-error at +1 {{must be tuple with any combination of 32-bit signless integer or 32-bit float values}}
   "test.tuple_32_bit"() : () -> (tuple<i64>)
   return
 }
@@ -58,7 +89,7 @@ func @tuple_wrong_type_scalar() {
 // -----
 
 func @tuple_wrong_type_tensor() {
-  // expected-error at +1 {{must be tuple with any combination of 32-bit integer or 32-bit float values}}
+  // expected-error at +1 {{must be tuple with any combination of 32-bit signless integer or 32-bit float values}}
   "test.tuple_32_bit"() : () -> (tuple<tensor<i32>>)
   return
 }
@@ -98,7 +129,7 @@ func @nested_tuple_multi_level_mixed_success() {
 // -----
 
 func @nested_tuple_multi_level_wrong_type() {
-  // expected-error at +1 {{must be nested tuple with any combination of 32-bit integer or 32-bit float values}}
+  // expected-error at +1 {{must be nested tuple with any combination of 32-bit signless integer or 32-bit float values}}
   "test.nested_tuple_32_bit"() : () -> (tuple<i32, tuple<i32, tuple<i64>>>)
   return
 }
@@ -117,7 +148,7 @@ func @rank_less_than_2_I8_F32_memref_success() {
 // -----
 
 func @rank_less_than_2_I8_F32_memref_bad_type() {
-  // expected-error at +1 {{must be 0D/1D memref of 8-bit integer or 32-bit float values}}
+  // expected-error at +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<i16>)
   return
 }
@@ -125,7 +156,7 @@ func @rank_less_than_2_I8_F32_memref_bad_type() {
 // -----
 
 func @rank_less_than_2_I8_F32_memref_bad_rank() {
-  // expected-error at +1 {{must be 0D/1D memref of 8-bit integer or 32-bit float values}}
+  // expected-error at +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_0d(%arg0: tensor<f32>, %arg1: tensor<10xf3
 // -----
 
 func @nd_tensor_of_success_wrong_type_4d(%arg0: tensor<f32>, %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<f32>, tensor<10xf32>, tensor<20x30xi16>, tensor<40x50x60xi16>, tensor<40x50x60xi16>) -> ()
   return
 }
@@ -193,7 +224,7 @@ func @multi_tensor_rank_of_success(%arg0: tensor<i8>, %arg1: tensor<i32>, %arg2:
 // -----
 
 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_unranked_type(%arg0: tensor<2x2xi8>) {
 // -----
 
 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(%ti32: tensor<* x i32>, %tf32: tensor<* x f32>, %mi32
 // -----
 
 func @fixed_element_types(%arg0: tensor<* x i32>, %arg1: tensor<* x f32>) {
-  // expected-error at +1 {{'res' is 16-bit integer}}
+  // expected-error at +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 @does_not_have_static_memref(%arg0: memref<?xi32>) {
 // -----
 
 func @elements_attr_not_i32_f32() {
-  // expected-error at +1 {{32-bit integer elements attribute}}
+  // expected-error at +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_f32() {
 // -----
 
 func @elements_attr_not_i32_i64() {
-  // expected-error at +1 {{32-bit integer elements attribute}}
+  // expected-error at +1 {{32-bit signless integer elements attribute}}
   "test.i32ElementsAttr"() {attr = dense<[1, 20]>:tensor<2xi64>} : () -> ()
   return
 }


        


More information about the Mlir-commits mailing list