Simplify and enable pretty-parsing/printing of the uniform quantized types.
authorStella Laurenzo <laurenzo@google.com>
Fri, 19 Apr 2019 21:41:31 +0000 (14:41 -0700)
committerMehdi Amini <joker.eph@gmail.com>
Wed, 24 Apr 2019 05:01:18 +0000 (22:01 -0700)
    The per-layer format is now like:
      !quant.uniform<i8<-8:7>:f32, 9.987200e-01:127>
    and per-axis is:
      !quant.uniform<i8:f32:1, {2.0e+2,0.99872:120}>

    I used the following sed script to update the unit tests (invoked with commands like `sed -i -r -f fix_quant.sed $(find . -name '*.mlir')`).
    ---
    # Per-layer
    s|\!quant<"uniform\[([iu][0-9]+):([fb]+[0-9]+)\]\{([^\}]+)\}\s*">|!quant.uniform<\1:\2, \3>|g
    s|\!quant<"uniform\[([iu][0-9]+)\(([^\)]+)\):([fb]+[0-9]+)\]\{([^\}]+)\}\s*">|!quant.uniform<\1<\2>:\3, \4>|g

    # Per-axis
    s|\!quant<"uniform\[([iu][0-9]+):([fb]+[0-9]+)(:[0-9]+)?\]\{([^\}]+)\}\s*">|!quant.uniform<\1:\2\3, {\4}>|g
    s|\!quant<"uniform\[([iu][0-9]+)\(([^\)]+)\):([fb]+[0-9]+)(:[0-9]+)?\]\{([^\}]+)\}\s*">|!quant.uniform<\1<\2>:\3\4, {\5}>|g
    ---
    I fixed up the one file of error cases manually.
    Since this is a one time syntax fix, I am not persisting the script anywhere.

--

PiperOrigin-RevId: 244425331

mlir/lib/IR/AsmPrinter.cpp
mlir/lib/Quantization/IR/TypeParser.cpp
mlir/test/FxpMathOps/lower-uniform-real-math-addew.mlir
mlir/test/FxpMathOps/lower-uniform-real-math-mulew.mlir
mlir/test/Quantization/canonicalize.mlir
mlir/test/Quantization/convert-const.mlir
mlir/test/Quantization/convert-fakequant.mlir
mlir/test/Quantization/parse-uniform-invalid.mlir
mlir/test/Quantization/parse-uniform.mlir

index 285ae77..02550b3 100644 (file)
@@ -752,11 +752,11 @@ static bool isDialectTypeSimpleEnoughForPrettyForm(StringRef typeName) {
         return false;
       break;
     case ')':
-      if (nestedPunctuation.pop_back_val() != ')')
+      if (nestedPunctuation.pop_back_val() != '(')
         return false;
       break;
     case '}':
-      if (nestedPunctuation.pop_back_val() != '}')
+      if (nestedPunctuation.pop_back_val() != '{')
         return false;
       break;
     default:
index 6610c28..cd26716 100644 (file)
@@ -67,12 +67,10 @@ namespace {
 enum class TokenKind {
   error,
   eof,
-  l_bracket,
-  r_bracket,
   l_brace,
   r_brace,
-  l_paren,
-  r_paren,
+  l_angle,
+  r_angle,
   colon,
   comma,
   alpha_ident,
@@ -144,18 +142,14 @@ Token Lexer::lexToken() {
 
     return emitError(tokStart, "unexpected character");
 
-  case '[':
-    return formToken(TokenKind::l_bracket, tokStart);
-  case ']':
-    return formToken(TokenKind::r_bracket, tokStart);
+  case '<':
+    return formToken(TokenKind::l_angle, tokStart);
+  case '>':
+    return formToken(TokenKind::r_angle, tokStart);
   case '{':
     return formToken(TokenKind::l_brace, tokStart);
   case '}':
     return formToken(TokenKind::r_brace, tokStart);
-  case '(':
-    return formToken(TokenKind::l_paren, tokStart);
-  case ')':
-    return formToken(TokenKind::r_paren, tokStart);
   case ':':
     return formToken(TokenKind::colon, tokStart);
   case ',':
@@ -312,17 +306,17 @@ Type TypeParser::parseType() {
 
 /// Parses a UniformQuantizedType.
 ///
-///   uniform_type ::= `uniform` type_spec quant_param_spec
-///
-///   type_spec ::= `[` storage-spec `:` expressed-type (quant-dim)? `]`
-///   quant-dim ::= `:` integer-literal
-///   storage-spec ::= storage-type (`(` storage-range `)`)?
+///   uniform_type ::= uniform_per_layer
+///                  | uniform_per_axis
+///   uniform_per_layer ::= `uniform<` storage-spec `,` scale-zero `>`
+///   uniform_per_axis ::= `uniform<` storage-spec axis-spec
+///                        `,` scale-zero-list `>`
+///   storage-spec ::= storage-type (`<` storage-range `>`)?
 ///   storage-range ::= integer-literal `:` integer-literal
 ///   storage-type ::= (`i` | `u`) integer-literal
-///   expressed-type ::= (`f16` | `f32` | `f64` | `bf16`)
-///
-///   quant_param_spec ::= `{` scale-zero (`,` scale-zero )* `}`
+///   axis-spec ::= `:` integer-literal
 ///   scale-zero ::= float-literal `:` integer-literal
+///   scale-zero-list ::= `{` scale-zero (`,` scale-zero)* `}`
 Type TypeParser::parseUniformType() {
   IntegerType storageType;
   FloatType expressedType;
@@ -335,7 +329,7 @@ Type TypeParser::parseUniformType() {
   SmallVector<int64_t, 1> zeroPoints;
 
   // Type specification.
-  if (!consumeIf(TokenKind::l_bracket)) {
+  if (!consumeIf(TokenKind::l_angle)) {
     return (emitError("unrecognized token: " + curToken.spelling), nullptr);
   }
 
@@ -354,7 +348,7 @@ Type TypeParser::parseUniformType() {
       isSigned, storageType.getWidth());
   int64_t defaultIntegerMax = QuantizedType::getDefaultMaxinumForInteger(
       isSigned, storageType.getWidth());
-  if (consumeIf(TokenKind::l_paren)) {
+  if (consumeIf(TokenKind::l_angle)) {
     // Explicit storage min and storage max.
     if (curToken.kind != TokenKind::integer_literal) {
       return (emitError("expected storage type minimum"), nullptr);
@@ -380,7 +374,7 @@ Type TypeParser::parseUniformType() {
     }
     consumeToken(TokenKind::integer_literal);
 
-    if (!consumeIf(TokenKind::r_paren)) {
+    if (!consumeIf(TokenKind::r_angle)) {
       return (emitError("unrecognized token: " + curToken.spelling), nullptr);
     }
   } else {
@@ -410,13 +404,17 @@ Type TypeParser::parseUniformType() {
     isPerAxis = true;
   }
 
-  if (!consumeIf(TokenKind::r_bracket)) {
+  // Comma leading into range_spec.
+  if (!consumeIf(TokenKind::comma)) {
     return (emitError("unrecognized token: " + curToken.spelling), nullptr);
   }
 
   // Parameter specification.
-  if (!consumeIf(TokenKind::l_brace)) {
-    return (emitError("unrecognized token: " + curToken.spelling), nullptr);
+  // For per-axis, ranges are in a {} delimitted list.
+  if (isPerAxis) {
+    if (!consumeIf(TokenKind::l_brace)) {
+      return (emitError("unrecognized token: " + curToken.spelling), nullptr);
+    }
   }
 
   // Parse scales/zeroPoints.
@@ -426,9 +424,15 @@ Type TypeParser::parseUniformType() {
     if (parseQuantParams(scales.back(), zeroPoints.back())) {
       return nullptr;
     }
-  } while (consumeIf(TokenKind::comma));
+  } while (isPerAxis && consumeIf(TokenKind::comma));
 
-  if (!consumeIf(TokenKind::r_brace)) {
+  if (isPerAxis) {
+    if (!consumeIf(TokenKind::r_brace)) {
+      return (emitError("unrecognized token: " + curToken.spelling), nullptr);
+    }
+  }
+
+  if (!consumeIf(TokenKind::r_angle)) {
     return (emitError("unrecognized token: " + curToken.spelling), nullptr);
   }
 
@@ -567,8 +571,8 @@ static void printStorageType(QuantizedType type, raw_ostream &out) {
       QuantizedType::getDefaultMaxinumForInteger(isSigned, storageWidth);
   if (defaultIntegerMin != type.getStorageTypeMin() ||
       defaultIntegerMax != type.getStorageTypeMax()) {
-    out << "(" << type.getStorageTypeMin() << ":" << type.getStorageTypeMax()
-        << ")";
+    out << "<" << type.getStorageTypeMin() << ":" << type.getStorageTypeMax()
+        << ">";
   }
 }
 
@@ -599,28 +603,27 @@ static void printQuantParams(double scale, int64_t zeroPoint,
 /// Helper that prints a UniformQuantizedType.
 static void printUniformQuantizedType(UniformQuantizedType type,
                                       raw_ostream &out) {
-  out << "uniform[";
+  out << "uniform<";
   printStorageType(type, out);
   out << ":";
   printExpressedType(type, out);
-  out << "]";
+  out << "";
 
   // scheme specific parameters
-  out << "{";
   printQuantParams(type.getScale(), type.getZeroPoint(), out);
-  out << "}";
+  out << ">";
 }
 
 /// Helper that prints a UniformQuantizedPerAxisType.
 static void printUniformQuantizedPerAxisType(UniformQuantizedPerAxisType type,
                                              raw_ostream &out) {
-  out << "uniform[";
+  out << "uniform<";
   printStorageType(type, out);
   out << ":";
   printExpressedType(type, out);
   out << ":";
   out << type.getQuantizedDimension();
-  out << "]";
+  out << "";
 
   // scheme specific parameters
   ArrayRef<double> scales = type.getScales();
@@ -632,7 +635,7 @@ static void printUniformQuantizedPerAxisType(UniformQuantizedPerAxisType type,
       out << ",";
     }
   }
-  out << "}";
+  out << "}>";
 }
 
 /// Print a type registered to this dialect.
index 4258cf7..a1c2e2d 100644 (file)
@@ -3,19 +3,19 @@
 // -----
 // Verify lowering when operands and result have the same fixedpoint scale.
 // CHECK-LABEL: real_addew_fixedpoint_isomorphic
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
 func @real_addew_fixedpoint_isomorphic(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
-  // CHECK-NEXT: %0 = "quant.scast"(%arg0) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>) -> tensor<4xi8>
-  // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>) -> tensor<4xi8>
+  // CHECK-NEXT: %0 = "quant.scast"(%arg0) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>) -> tensor<4xi8>
+  // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>) -> tensor<4xi8>
   // CHECK-NEXT: %2 = "fxpmath.convertis"(%0) : (tensor<4xi8>) -> tensor<4xi16>
   // CHECK-NEXT: %3 = "fxpmath.convertis"(%1) : (tensor<4xi8>) -> tensor<4xi16>
   // CHECK-NEXT: %4 = addi %2, %3 : tensor<4xi16>
   // CHECK-NEXT: %5 = "fxpmath.clampis"(%4) {clamp_max: 127 : i16, clamp_min: -128 : i16} : (tensor<4xi16>) -> tensor<4xi16>
   // CHECK-NEXT: %6 = "fxpmath.convertis"(%5) : (tensor<4xi16>) -> tensor<4xi8>
-  // CHECK-NEXT: %7 = "quant.scast"(%6) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>
-  // CHECK-NEXT: return %7 : tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>
+  // CHECK-NEXT: %7 = "quant.scast"(%6) : (tensor<4xi8>) -> tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>
+  // CHECK-NEXT: return %7 : tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>
   %0 = "fxpmath.real_add_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
   return %0 : !type_result
 }
@@ -24,21 +24,21 @@ func @real_addew_fixedpoint_isomorphic(%arg0 : !type_lhs, %arg1: !type_rhs) -> !
 // Verify lowering when operands and result have the same fixedpoint scale
 // and non-zero zero points.
 // CHECK-LABEL: real_addew_affine_isomorphic
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2:-5}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2:-5}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2:-5}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2:-5>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2:-5>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2:-5>>
 func @real_addew_affine_isomorphic(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
   // CHECK-NEXT: %cst = constant splat<tensor<4xi16>, 5> : tensor<4xi16>
-  // CHECK-NEXT: %0 = "quant.scast"(%arg0) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02:-5}">>) -> tensor<4xi8>
-  // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02:-5}">>) -> tensor<4xi8>
+  // CHECK-NEXT: %0 = "quant.scast"(%arg0) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02:-5>>) -> tensor<4xi8>
+  // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02:-5>>) -> tensor<4xi8>
   // CHECK-NEXT: %2 = "fxpmath.convertis"(%0) : (tensor<4xi8>) -> tensor<4xi16>
   // CHECK-NEXT: %3 = "fxpmath.convertis"(%1) : (tensor<4xi8>) -> tensor<4xi16>
   // CHECK-NEXT: %4 = addi %2, %3 : tensor<4xi16>
   // CHECK-NEXT: %5 = addi %4, %cst : tensor<4xi16>
   // CHECK-NEXT: %6 = "fxpmath.clampis"(%5) {clamp_max: 127 : i16, clamp_min: -128 : i16} : (tensor<4xi16>) -> tensor<4xi16>
   // CHECK-NEXT: %7 = "fxpmath.convertis"(%6) : (tensor<4xi16>) -> tensor<4xi8>
-  // CHECK-NEXT: %8 = "quant.scast"(%7) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[i8:f32]{6.250000e-02:-5}">>
-  // CHECK-NEXT: return %8 : tensor<4x!quant<"uniform[i8:f32]{6.250000e-02:-5}">>
+  // CHECK-NEXT: %8 = "quant.scast"(%7) : (tensor<4xi8>) -> tensor<4x!quant.uniform<i8:f32, 6.250000e-02:-5>>
+  // CHECK-NEXT: return %8 : tensor<4x!quant.uniform<i8:f32, 6.250000e-02:-5>>
   %0 = "fxpmath.real_add_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
   return %0 : !type_result
 }
@@ -47,19 +47,19 @@ func @real_addew_affine_isomorphic(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type
 // The RHS quant parameters proscribe a range of [-8..8) so an explicit clamp
 // of [-4..4] should result in an integral clamp range of [-64..64].
 // CHECK-LABEL: real_addew_fixedpoint_clamp
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
 func @real_addew_fixedpoint_clamp(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
-  // CHECK-NEXT: %0 = "quant.scast"(%arg0) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>) -> tensor<4xi8>
-  // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>) -> tensor<4xi8>
+  // CHECK-NEXT: %0 = "quant.scast"(%arg0) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>) -> tensor<4xi8>
+  // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>) -> tensor<4xi8>
   // CHECK-NEXT: %2 = "fxpmath.convertis"(%0) : (tensor<4xi8>) -> tensor<4xi16>
   // CHECK-NEXT: %3 = "fxpmath.convertis"(%1) : (tensor<4xi8>) -> tensor<4xi16>
   // CHECK-NEXT: %4 = addi %2, %3 : tensor<4xi16>
   // CHECK-NEXT: %5 = "fxpmath.clampis"(%4) {clamp_max: 64 : i16, clamp_min: -64 : i16} : (tensor<4xi16>) -> tensor<4xi16>
   // CHECK-NEXT: %6 = "fxpmath.convertis"(%5) : (tensor<4xi16>) -> tensor<4xi8>
-  // CHECK-NEXT: %7 = "quant.scast"(%6) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>
-  // CHECK-NEXT: return %7 : tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>
+  // CHECK-NEXT: %7 = "quant.scast"(%6) : (tensor<4xi8>) -> tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>
+  // CHECK-NEXT: return %7 : tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>
   %0 = "fxpmath.real_add_ew"(%arg0, %arg1) { clamp_min:-4.0, clamp_max:4.0 }
       : (!type_lhs, !type_rhs) -> (!type_result)
   return %0 : !type_result
@@ -69,8 +69,8 @@ func @real_addew_fixedpoint_clamp(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_
 // CHECK-LABEL: real_addew_unquantized_lhs
 // Verifies that leaves as-is for unquantized lhs.
 !type_lhs = type tensor<4xf32>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
 func @real_addew_unquantized_lhs(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
   // CHECK: %0 = "fxpmath.real_add_ew"(%arg0, %arg1)
   %0 = "fxpmath.real_add_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
@@ -80,9 +80,9 @@ func @real_addew_unquantized_lhs(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_r
 // -----
 // CHECK-LABEL: real_addew_unquantized_rhs
 // Verifies that leaves as-is for unquantized rhs.
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
 !type_rhs = type tensor<4xf32>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
 func @real_addew_unquantized_rhs(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
   // CHECK: %0 = "fxpmath.real_add_ew"(%arg0, %arg1)
   %0 = "fxpmath.real_add_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
@@ -92,8 +92,8 @@ func @real_addew_unquantized_rhs(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_r
 // -----
 // CHECK-LABEL: real_addew_unquantized_result
 // Verifies that leaves as-is for unquantized result.
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
 !type_result = type tensor<4xf32>
 func @real_addew_unquantized_result(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
   // CHECK: %0 = "fxpmath.real_add_ew"(%arg0, %arg1)
index 8106612..d62cfc2 100644 (file)
@@ -3,12 +3,12 @@
 // -----
 // Verify lowering when operands and result have the same fixedpoint scale.
 // CHECK-LABEL: real_mulew_fixedpoint
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{3.875e-2}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{1.065e-1}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 3.875e-2>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 1.065e-1>>
 func @real_mulew_fixedpoint(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
-  // CHECK: %0 = "quant.scast"(%arg0) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>) -> tensor<4xi8>
-  // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant<"uniform[i8:f32]{3.875000e-02}">>) -> tensor<4xi8>
+  // CHECK: %0 = "quant.scast"(%arg0) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>) -> tensor<4xi8>
+  // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant.uniform<i8:f32, 3.875000e-02>>) -> tensor<4xi8>
   // CHECK-NEXT: %2 = "fxpmath.convertis"(%0) : (tensor<4xi8>) -> tensor<4xi32>
   // CHECK-NEXT: %3 = "fxpmath.convertis"(%1) : (tensor<4xi8>) -> tensor<4xi32>
   // CHECK-NEXT: %4 = muli %2, %3 : tensor<4xi32>
@@ -16,8 +16,8 @@ func @real_mulew_fixedpoint(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result
   // CHECK-NEXT: %6 = "fxpmath.rounding_divide_by_potis"(%5) {exponent: 5 : i32} : (tensor<4xi32>) -> tensor<4xi32>
   // CHECK-NEXT: %7 = "fxpmath.clampis"(%6) {clamp_max: 127 : i32, clamp_min: -128 : i32} : (tensor<4xi32>) -> tensor<4xi32>
   // CHECK-NEXT: %8 = "fxpmath.convertis"(%7) : (tensor<4xi32>) -> tensor<4xi8>
-  // CHECK-NEXT: %9 = "quant.scast"(%8) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[i8:f32]{1.065000e-01}">>
-  // CHECK-NEXT: return %9 : tensor<4x!quant<"uniform[i8:f32]{1.065000e-01}">>
+  // CHECK-NEXT: %9 = "quant.scast"(%8) : (tensor<4xi8>) -> tensor<4x!quant.uniform<i8:f32, 1.065000e-01>>
+  // CHECK-NEXT: return %9 : tensor<4x!quant.uniform<i8:f32, 1.065000e-01>>
   %0 = "fxpmath.real_mul_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
   return %0 : !type_result
 }
@@ -26,9 +26,9 @@ func @real_mulew_fixedpoint(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result
 // Verify lowering when operands and result have the same fixedpoint scale
 // and non-zero zero points.
 // CHECK-LABEL: real_mulew_affine_clamp
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2:-3}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2:-5}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2:-9}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2:-3>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2:-5>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2:-9>>
 func @real_mulew_affine_clamp(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
   // Just verify that the affine adds/constants and clamps are present.
   // CHECK: %cst = constant splat<tensor<4xi32>, 3> : tensor<4xi32>
@@ -47,8 +47,8 @@ func @real_mulew_affine_clamp(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_resu
 // CHECK-LABEL: real_mulew_unquantized_lhs
 // Verifies that leaves as-is for unquantized lhs.
 !type_lhs = type tensor<4xf32>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
 func @real_mulew_unquantized_lhs(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
   // CHECK: %0 = "fxpmath.real_mul_ew"(%arg0, %arg1)
   %0 = "fxpmath.real_mul_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
@@ -58,9 +58,9 @@ func @real_mulew_unquantized_lhs(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_r
 // -----
 // CHECK-LABEL: real_mulew_unquantized_rhs
 // Verifies that leaves as-is for unquantized rhs.
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
 !type_rhs = type tensor<4xf32>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
 func @real_mulew_unquantized_rhs(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
   // CHECK: %0 = "fxpmath.real_mul_ew"(%arg0, %arg1)
   %0 = "fxpmath.real_mul_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
@@ -70,8 +70,8 @@ func @real_mulew_unquantized_rhs(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_r
 // -----
 // CHECK-LABEL: real_mulew_unquantized_result
 // Verifies that leaves as-is for unquantized result.
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
 !type_result = type tensor<4xf32>
 func @real_mulew_unquantized_result(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
   // CHECK: %0 = "fxpmath.real_mul_ew"(%arg0, %arg1)
@@ -84,9 +84,9 @@ func @real_mulew_unquantized_result(%arg0 : !type_lhs, %arg1: !type_rhs) -> !typ
 // Note that the multiplier = lhs_scale * rhs_scale / result_scale
 //   = 22.740610328638496
 // CHECK-LABEL: real_mulew_multiplier_gt_1
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{3.875e-2}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{1.065e-4}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 3.875e-2>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 1.065e-4>>
 func @real_mulew_multiplier_gt_1(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
   // expected-warning@+1 {{unimplemented: cannot multiply with multipler > 1.0}}
   %0 = "fxpmath.real_mul_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
index 5cfd59a..abc851c 100644 (file)
@@ -6,19 +6,19 @@ func @redundant_scast() -> tensor<4xi8> {
   // CHECK-NEXT: constant splat<tensor<4xi8>, 10>
   // CHECK-NEXT: return
   %cst = constant splat<tensor<4xi8>, 5> : tensor<4xi8>
-  %1 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>
-  %2 = "quant.scast"(%1) : (tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>) -> tensor<4xi8>
+  %1 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>
+  %2 = "quant.scast"(%1) : (tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>) -> tensor<4xi8>
   %3 = addi %2, %2 : tensor<4xi8>
   return %3 : tensor<4xi8>
 }
 
 // -----
 // CHECK-LABEL: non_redundant_scast
-func @non_redundant_scast() -> tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">> {
+func @non_redundant_scast() -> tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>> {
   // CHECK-NEXT: constant splat<tensor<4xi8>, 5>
   // CHECK-NEXT: scast
   // CHECK-NEXT: return
   %cst = constant splat<tensor<4xi8>, 5> : tensor<4xi8>
-  %1 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>
-  return %1 : tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>
+  %1 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>
+  return %1 : tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>
 }
index 21aa66d..1d28fa4 100644 (file)
 // CHECK-LABEL: constant_splat_tensor_u8_affine
 func @constant_splat_tensor_u8_affine() -> tensor<4xf32> {
   // CHECK: %cst = constant splat<tensor<4xi8>, -64> : tensor<4xi8>
-  // CHECK-NEXT: %0 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>
+  // CHECK-NEXT: %0 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>
   %cst = constant splat<tensor<4xf32>, 0.5> : tensor<4xf32>
-  %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>
-  %2 = "quant.dcast"(%1) : (tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>) -> (tensor<4xf32>)
+  %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>
+  %2 = "quant.dcast"(%1) : (tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>) -> (tensor<4xf32>)
   return %2 : tensor<4xf32>
 }
 
@@ -24,10 +24,10 @@ func @constant_splat_tensor_u8_affine() -> tensor<4xf32> {
 // CHECK-LABEL: constant_splat_tensor_i8_affine
 func @constant_splat_tensor_i8_affine() -> tensor<4xf32> {
   // CHECK: %cst = constant splat<tensor<4xi8>, 63> : tensor<4xi8>
-  // CHECK-NEXT: %0 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[i8:f32]{7.812500e-03:-1}">>
+  // CHECK-NEXT: %0 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant.uniform<i8:f32, 7.812500e-03:-1>>
   %cst = constant splat<tensor<4xf32>, 0.5> : tensor<4xf32>
-  %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant<"uniform[i8:f32]{7.812500e-03:-1}">>
-  %2 = "quant.dcast"(%1) : (tensor<4x!quant<"uniform[i8:f32]{7.812500e-03:-1}">>) -> (tensor<4xf32>)
+  %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant.uniform<i8:f32, 7.812500e-03:-1>>
+  %2 = "quant.dcast"(%1) : (tensor<4x!quant.uniform<i8:f32, 7.812500e-03:-1>>) -> (tensor<4xf32>)
   return %2 : tensor<4xf32>
 }
 
@@ -36,10 +36,10 @@ func @constant_splat_tensor_i8_affine() -> tensor<4xf32> {
 // CHECK-LABEL: const_splat_tensor_i8_fixedpoint
 func @const_splat_tensor_i8_fixedpoint() -> tensor<4xf32> {
   // CHECK: %cst = constant splat<tensor<4xi8>, 64> : tensor<4xi8>
-  // CHECK-NEXT: %0 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[i8:f32]{7.812500e-03}">>
+  // CHECK-NEXT: %0 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant.uniform<i8:f32, 7.812500e-03>>
   %cst = constant splat<tensor<4xf32>, 0.5> : tensor<4xf32>
-  %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant<"uniform[i8:f32]{7.812500e-03}">>
-  %2 = "quant.dcast"(%1) : (tensor<4x!quant<"uniform[i8:f32]{7.812500e-03}">>) -> (tensor<4xf32>)
+  %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant.uniform<i8:f32, 7.812500e-03>>
+  %2 = "quant.dcast"(%1) : (tensor<4x!quant.uniform<i8:f32, 7.812500e-03>>) -> (tensor<4xf32>)
   return %2 : tensor<4xf32>
 }
 
@@ -49,8 +49,8 @@ func @const_splat_tensor_i8_fixedpoint() -> tensor<4xf32> {
 func @const_splat_tensor_i8_fixedpoint_neg() -> tensor<4xf32> {
   // CHECK: %cst = constant splat<tensor<4xi8>, -64> : tensor<4xi8>
   %cst = constant splat<tensor<4xf32>, -0.5> : tensor<4xf32>
-  %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant<"uniform[i8:f32]{7.812500e-03}">>
-  %2 = "quant.dcast"(%1) : (tensor<4x!quant<"uniform[i8:f32]{7.812500e-03}">>) -> (tensor<4xf32>)
+  %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant.uniform<i8:f32, 7.812500e-03>>
+  %2 = "quant.dcast"(%1) : (tensor<4x!quant.uniform<i8:f32, 7.812500e-03>>) -> (tensor<4xf32>)
   return %2 : tensor<4xf32>
 }
 
@@ -60,8 +60,8 @@ func @const_splat_tensor_i8_fixedpoint_neg() -> tensor<4xf32> {
 func @const_dense_tensor_i8_fixedpoint() -> tensor<7xf32> {
   // CHECK: %cst = constant dense<tensor<7xi8>, [-128, -128, -64, 0, 64, 127, 127]> : tensor<7xi8>
   %cst = constant dense<tensor<7xf32>, [-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0]> : tensor<7xf32>
-  %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant<"uniform[i8:f32]{7.812500e-03}">>
-  %2 = "quant.dcast"(%1) : (tensor<7x!quant<"uniform[i8:f32]{7.812500e-03}">>) -> (tensor<7xf32>)
+  %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant.uniform<i8:f32, 7.812500e-03>>
+  %2 = "quant.dcast"(%1) : (tensor<7x!quant.uniform<i8:f32, 7.812500e-03>>) -> (tensor<7xf32>)
   return %2 : tensor<7xf32>
 }
 
@@ -74,8 +74,8 @@ func @const_sparse_tensor_i8_fixedpoint() -> tensor<7x2xf32> {
   %cst = constant sparse<tensor<7x2xf32>,
       [[0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6]],
       [-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0]> : tensor<7x2xf32>
-  %1 = "quant.qcast"(%cst) : (tensor<7x2xf32>) -> tensor<7x2x!quant<"uniform[i8:f32]{7.812500e-03}">>
-  %2 = "quant.dcast"(%1) : (tensor<7x2x!quant<"uniform[i8:f32]{7.812500e-03}">>) -> (tensor<7x2xf32>)
+  %1 = "quant.qcast"(%cst) : (tensor<7x2xf32>) -> tensor<7x2x!quant.uniform<i8:f32, 7.812500e-03>>
+  %2 = "quant.dcast"(%1) : (tensor<7x2x!quant.uniform<i8:f32, 7.812500e-03>>) -> (tensor<7x2xf32>)
   return %2 : tensor<7x2xf32>
 }
 
@@ -84,10 +84,10 @@ func @const_sparse_tensor_i8_fixedpoint() -> tensor<7x2xf32> {
 // CHECK-LABEL: const_primitive_float_i8_fixedpoint
 func @const_primitive_float_i8_fixedpoint() -> f32 {
   // CHECK: %c64_i8 = constant 64 : i8
-  // CHECK-NEXT: %0 = "quant.scast"(%c64_i8) : (i8) -> !quant<"uniform[i8:f32]{7.812500e-03}">
+  // CHECK-NEXT: %0 = "quant.scast"(%c64_i8) : (i8) -> !quant.uniform<i8:f32, 7.812500e-03>
   %cst = constant 0.5 : f32
-  %1 = "quant.qcast"(%cst) : (f32) -> !quant<"uniform[i8:f32]{7.812500e-03}">
-  %2 = "quant.dcast"(%1) : (!quant<"uniform[i8:f32]{7.812500e-03}">) -> (f32)
+  %1 = "quant.qcast"(%cst) : (f32) -> !quant.uniform<i8:f32, 7.812500e-03>
+  %2 = "quant.dcast"(%1) : (!quant.uniform<i8:f32, 7.812500e-03>) -> (f32)
   return %2 : f32
 }
 
@@ -98,8 +98,8 @@ func @const_dense_tensor_u4_affine() -> tensor<7xf32> {
   // NOTE: Unsigned quantities printed by MLIR as signed.
   // CHECK: %cst = constant dense<tensor<7xi4>, [0, 0, 4, -8, -4, -1, -1]> : tensor<7xi4>
   %cst = constant dense<tensor<7xf32>, [-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0]> : tensor<7xf32>
-  %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant<"uniform[u4:f32]{1.250000e-01:8}">>
-  %2 = "quant.dcast"(%1) : (tensor<7x!quant<"uniform[u4:f32]{1.250000e-01:8}">>) -> (tensor<7xf32>)
+  %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant.uniform<u4:f32, 1.250000e-01:8>>
+  %2 = "quant.dcast"(%1) : (tensor<7x!quant.uniform<u4:f32, 1.250000e-01:8>>) -> (tensor<7xf32>)
   return %2 : tensor<7xf32>
 }
 
@@ -110,8 +110,8 @@ func @const_dense_tensor_i4_affine() -> tensor<7xf32> {
   // NOTE: Unsigned quantities printed by MLIR as signed.
   // CHECK: %cst = constant dense<tensor<7xi4>, [-8, -8, -5, -1, 3, 7, 7]> : tensor<7xi4>
   %cst = constant dense<tensor<7xf32>, [-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0]> : tensor<7xf32>
-  %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant<"uniform[i4:f32]{1.250000e-01:-1}">>
-  %2 = "quant.dcast"(%1) : (tensor<7x!quant<"uniform[i4:f32]{1.250000e-01:-1}">>) -> (tensor<7xf32>)
+  %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant.uniform<i4:f32, 1.250000e-01:-1>>
+  %2 = "quant.dcast"(%1) : (tensor<7x!quant.uniform<i4:f32, 1.250000e-01:-1>>) -> (tensor<7xf32>)
   return %2 : tensor<7xf32>
 }
 
@@ -121,8 +121,8 @@ func @const_dense_tensor_i4_affine() -> tensor<7xf32> {
 func @const_dense_tensor_i4_fixedpoint() -> tensor<7xf32> {
   // CHECK: %cst = constant dense<tensor<7xi4>, [-8, -8, -4, 0, 4, 7, 7]> : tensor<7xi4>
   %cst = constant dense<tensor<7xf32>, [-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0]> : tensor<7xf32>
-  %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant<"uniform[i4:f32]{1.250000e-01}">>
-  %2 = "quant.dcast"(%1) : (tensor<7x!quant<"uniform[i4:f32]{1.250000e-01}">>) -> (tensor<7xf32>)
+  %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant.uniform<i4:f32, 1.250000e-01>>
+  %2 = "quant.dcast"(%1) : (tensor<7x!quant.uniform<i4:f32, 1.250000e-01>>) -> (tensor<7xf32>)
   return %2 : tensor<7xf32>
 }
 
@@ -134,7 +134,7 @@ func @const_dense_tensor_i4_fixedpoint() -> tensor<7xf32> {
 func @const_custom_storage_range_i8_fixedpoint() -> tensor<7xf32> {
   // CHECK: %cst = constant dense<tensor<7xi8>, [-100, -100, -64, 0, 64, 100, 100]> : tensor<7xi8>
   %cst = constant dense<tensor<7xf32>, [-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0]> : tensor<7xf32>
-  %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant<"uniform[i8(-100:100):f32]{7.812500e-03}">>
-  %2 = "quant.dcast"(%1) : (tensor<7x!quant<"uniform[i8(-100:100):f32]{7.812500e-03}">>) -> (tensor<7xf32>)
+  %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant.uniform<i8<-100:100>:f32, 7.812500e-03>>
+  %2 = "quant.dcast"(%1) : (tensor<7x!quant.uniform<i8<-100:100>:f32, 7.812500e-03>>) -> (tensor<7xf32>)
   return %2 : tensor<7xf32>
 }
index 38b2a6c..bfafb9a 100644 (file)
@@ -6,8 +6,8 @@
 func @fakeQuantArgs_Quint8_0_1(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> {
 ^bb0(%arg0: tensor<8x4x3xf32>):
   // CHECK: %0 = "quant.qcast"(%arg0) : (tensor<8x4x3xf32>)
-  // CHECK-SAME: -> tensor<8x4x3x!quant<"uniform[u8:f32]{0.0039215686274509803}">>
-  // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant<"uniform[u8:f32]{0.0039215686274509803}">>)
+  // CHECK-SAME: -> tensor<8x4x3x!quant.uniform<u8:f32, 0.0039215686274509803>>
+  // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant.uniform<u8:f32, 0.0039215686274509803>>)
   // CHECK-SAME: -> tensor<8x4x3xf32>
   %0 = "quant.const_fake_quant"(%arg0) {
     min: 0.0 : f32, max: 1.0 : f32, num_bits: 8
@@ -21,8 +21,8 @@ func @fakeQuantArgs_Quint8_0_1(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> {
 func @fakeQuantArgs_Quint8_NarrowRange(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> {
 ^bb0(%arg0: tensor<8x4x3xf32>):
   // CHECK: %0 = "quant.qcast"(%arg0) : (tensor<8x4x3xf32>)
-  // CHECK-SAME: -> tensor<8x4x3x!quant<"uniform[u8(1:255):f32]{0.003937007874015748:1}">>
-  // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant<"uniform[u8(1:255):f32]{0.003937007874015748:1}">>)
+  // CHECK-SAME: -> tensor<8x4x3x!quant.uniform<u8<1:255>:f32, 0.003937007874015748:1>>
+  // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant.uniform<u8<1:255>:f32, 0.003937007874015748:1>>)
   // CHECK-SAME: -> tensor<8x4x3xf32>
   %0 = "quant.const_fake_quant"(%arg0) {
     min: 0.0 : f32, max: 1.0 : f32, num_bits: 8, narrow_range: true
@@ -36,8 +36,8 @@ func @fakeQuantArgs_Quint8_NarrowRange(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> {
 func @fakeQuantArgs_Quint8_SymmetricRange(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> {
 ^bb0(%arg0: tensor<8x4x3xf32>):
   // CHECK: %0 = "quant.qcast"(%arg0) : (tensor<8x4x3xf32>)
-  // CHECK-SAME: -> tensor<8x4x3x!quant<"uniform[u8:f32]{7.812500e-03:128}">>
-  // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant<"uniform[u8:f32]{7.812500e-03:128}">>)
+  // CHECK-SAME: -> tensor<8x4x3x!quant.uniform<u8:f32, 7.812500e-03:128>>
+  // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant.uniform<u8:f32, 7.812500e-03:128>>)
   // CHECK-SAME: -> tensor<8x4x3xf32>
   %0 = "quant.const_fake_quant"(%arg0) {
     min: -1.0 : f32, max: 0.9921875 : f32, num_bits: 8, narrow_range: false
@@ -52,8 +52,8 @@ func @fakeQuantArgs_Quint8_SymmetricRange(tensor<8x4x3xf32>) -> tensor<8x4x3xf32
 func @fakeQuantArgs_Qint16_Symmetric(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> {
 ^bb0(%arg0: tensor<8x4x3xf32>):
   // CHECK: %0 = "quant.qcast"(%arg0) : (tensor<8x4x3xf32>)
-  // CHECK-SAME: -> tensor<8x4x3x!quant<"uniform[i16:f32]{3.0517578125E-5}">>
-  // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant<"uniform[i16:f32]{3.0517578125E-5}">>)
+  // CHECK-SAME: -> tensor<8x4x3x!quant.uniform<i16:f32, 3.0517578125E-5>>
+  // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant.uniform<i16:f32, 3.0517578125E-5>>)
   // CHECK-SAME: -> tensor<8x4x3xf32>
   %0 = "quant.const_fake_quant"(%arg0) {
     min: -1.0 : f32, max: 0.999969482 : f32, num_bits: 16
@@ -67,8 +67,8 @@ func @fakeQuantArgs_Qint16_Symmetric(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> {
 func @fakeQuantArgs_UnrankedTensor(tensor<f32>) -> tensor<f32> {
 ^bb0(%arg0: tensor<f32>):
   // CHECK: %0 = "quant.qcast"(%arg0) : (tensor<f32>)
-  // CHECK-SAME: -> tensor<!quant<"uniform[u8:f32]{0.0039215686274509803}">>
-  // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<!quant<"uniform[u8:f32]{0.0039215686274509803}">>)
+  // CHECK-SAME: -> tensor<!quant.uniform<u8:f32, 0.0039215686274509803>>
+  // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<!quant.uniform<u8:f32, 0.0039215686274509803>>)
   // CHECK-SAME: -> tensor<f32>
   %0 = "quant.const_fake_quant"(%arg0) {
     min: 0.0 : f32, max: 1.0 : f32, num_bits: 8
index f6d872c..d046fc9 100644 (file)
 // -----
 // Invalid type.
 // expected-error@+1 {{unknown quantized type foobar}}
-!qalias = type !quant<"foobar">
+!qalias = type !quant.foobar
 
 // -----
 // Unrecognized token: illegal token
-// expected-error@+1 {{unrecognized token: %}}
-!qalias = type !quant<"%%">
+// expected-error@+1 {{unrecognized token: _}}
+!qalias = type !quant.__
 
 // -----
 // Unrecognized token: trailing
 // expected-error@+1 {{unrecognized token: 23}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{0.99872:127} 23">
-
-// -----
-// Unrecognized token: type open
-// expected-error@+1 {{unrecognized token: (}}
-!qalias = type !quant<"uniform(i8(-4:3):f32){0.99872:127}">
+!qalias = type !quant.uniform<i8<-4:3>:f32, 0.99872:127 23>
 
 // -----
 // Unrecognized token: missing storage type maximum
-// expected-error@+1 {{expected storage type maximum}}
-!qalias = type !quant<"uniform[i8(16:f32]{0.99872:127}">
+// expected-error@+1 {{unrecognized token: >}}
+!qalias = type !quant.uniform<i8<16>:f32, 0.99872:127>
 
 // -----
-// Unrecognized token: missing closing paren
+// Unrecognized token: missing closing angle bracket
 // expected-error@+1 {{unrecognized token: :}}
-!qalias = type !quant<"uniform[i8(-4:3:f32]{0.99872:127}">
+!qalias = type !quant<"uniform<i8<-4:3:f32, 0.99872:127>">
 
 // -----
 // Unrecognized token: missing type colon
 // expected-error@+1 {{unrecognized token: f}}
-!qalias = type !quant<"uniform[i8(-4:3)f32]{0.99872:127}">
-
-// -----
-// Unrecognized token: missing closing bracket
-// expected-error@+1 {{unrecognized token: {}}
-!qalias = type !quant<"uniform[i8(-4:3):f32{0.99872:127}">
+!qalias = type !quant.uniform<i8<-4:3>f32, 0.99872:127>
 
 // -----
-// Unrecognized token: wrong opening brace
-// expected-error@+1 {{unrecognized token: (}}
-!qalias = type !quant<"uniform[i8(-4:3):f32](0.99872:127}">
+// Unrecognized token: missing comma
+// expected-error@+1 {{unrecognized token: 0.99872}}
+!qalias = type !quant.uniform<i8<-4:3>:f32 0.99872:127>
 
 // -----
 // Unrecognized storage type: illegal prefix
 // expected-error@+1 {{illegal storage type prefix: int}}
-!qalias = type !quant<"uniform[int8(-4:3):f32]{0.99872:127}">
+!qalias = type !quant.uniform<int8<-4:3>:f32, 0.99872:127>
 
 // -----
 // Unrecognized storage type: no width
 // expected-error@+1 {{expected storage type width}}
-!qalias = type !quant<"uniform[i(-4:3):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i<-4:3>:f32, 0.99872:127>
 
 // -----
 // Unrecognized storage type: storage size > 32
 // expected-error@+1 {{illegal storage type size: 33}}
-!qalias = type !quant<"uniform[i33:f32]{0.99872:127}">
+!qalias = type !quant.uniform<i33:f32, 0.99872:127>
 
 // -----
 // Unrecognized storage type: storage size < 0
 // expected-error@+1 {{illegal storage type size: -1}}
-!qalias = type !quant<"uniform[i-1(-4:3):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i-1<-4:3>:f32, 0.99872:127>
 
 // -----
 // Unrecognized storage type: storage size == 0
 // expected-error@+1 {{illegal storage type size: 0}}
-!qalias = type !quant<"uniform[i0(-4:3):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i0<-4:3>:f32, 0.99872:127>
 
 // -----
 // Illegal storage min/max: max - min < 0
 // expected-error@+1 {{illegal storage min and storage max: (2:1)}}
-!qalias = type !quant<"uniform[i8(2:1):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i8<2:1>:f32, 0.99872:127>
 
 // -----
 // Illegal storage min/max: max - min == 0
 // expected-error@+1 {{illegal storage min and storage max: (1:1)}}
-!qalias = type !quant<"uniform[i8(1:1):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i8<1:1>:f32, 0.99872:127>
 
 // -----
 // Illegal storage min/max: max > defaultMax
 // expected-error@+1 {{illegal storage type maximum: 9}}
-!qalias = type !quant<"uniform[i4(-1:9):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i4<-1:9>:f32, 0.99872:127>
 
 // -----
 // Illegal storage min/max: min < defaultMin
 // expected-error@+1 {{illegal storage type minimum: -9}}
-!qalias = type !quant<"uniform[i4(-9:1):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i4<-9:1>:f32, 0.99872:127>
 
 // -----
 // Illegal uniform params: invalid scale
 // expected-error@+1 {{expected valid uniform scale. got: abc}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{abc:127}">
+!qalias = type !quant.uniform<i8<-4:3>:f32, abc:127>
 
 // -----
 // Illegal uniform params: invalid zero point separator
 // expected-error@+1 {{unrecognized token: abc}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{0.1abc}">
+!qalias = type !quant.uniform<i8<-4:3>:f32, 0.1abc>
 
 // -----
 // Illegal uniform params: missing zero point
-// expected-error@+1 {{expected integer uniform zero point. got: }}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{0.1:}">
+// expected-error@+1 {{expected integer uniform zero point. got: >}}
+!qalias = type !quant.uniform<i8<-4:3>:f32, 0.1:>
 
 // -----
 // Illegal uniform params: invalid zero point
 // expected-error@+1 {{expected integer uniform zero point. got: abc}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{0.1:abc}">
-
-// -----
-// Illegal uniform params: missing closing brace
-// expected-error@+1 {{unrecognized token: )}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{0.1:0)">
+!qalias = type !quant.uniform<i8<-4:3>:f32, 0.1:abc>
 
 // -----
 // Illegal expressed type: f33
 // expected-error@+1 {{unrecognized expressed type: f33}}
-!qalias = type !quant<"uniform[i8(-4:3):f33]{0.99872:127}">
+!qalias = type !quant.uniform<i8<-4:3>:f33, 0.99872:127>
 
 // -----
 // Illegal scale: negative
 // expected-error@+1 {{illegal scale: -1.000000}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{-1.0:127}">
+!qalias = type !quant.uniform<i8<-4:3>:f32, -1.0:127>
 
 // -----
 // Illegal uniform params: missing quantized dimension
 // expected-error@+1 {{expected quantized dimension}}
-!qalias = type !quant<"uniform[i8(-4:3):f32:]{2.000000e+02:-19.987200e-01:1}">
+!qalias = type !quant.uniform<i8<-4:3>:f32:, {2.000000e+02:-19.987200e-01:1}>
 
 // -----
 // Illegal uniform params: unspecified quantized dimension, when multiple scales
 // provided.
-// expected-error@+1 {{multiple scales/zeroPoints provided, but quantizedDimension wasn't specified}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{2.000000e+02,-19.987200e-01:1}">
+// expected-error@+1 {{expected valid uniform scale. got: {}}
+!qalias = type !quant.uniform<i8<-4:3>:f32, {2.000000e+02,-19.987200e-01:1}>
index f29a93d..82d2ae6 100644 (file)
@@ -3,8 +3,8 @@
 // -----
 // All per-layer params specified:
 //   [signed] storageType, storageTypeMin, storageTypeMax, expressedType, scale, zeroPoint
-// CHECK: !quant<"uniform[i8(-8:7):f32]{9.987200e-01:127}">
-!qalias = type !quant<"uniform[i8(-8:7):f32]{0.99872:127}">
+// CHECK: !quant.uniform<i8<-8:7>:f32, 9.987200e-01:127>
+!qalias = type !quant.uniform<i8<-8:7>:f32, 0.99872:127>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -12,8 +12,8 @@ func @parse() -> !qalias {
 
 // -----
 // Trailing whitespace.
-// CHECK: !quant<"uniform[i8(-8:7):f32]{9.987200e-01:127}">
-!qalias = type !quant<"uniform[i8(-8:7):f32]{0.99872:127}  ">
+// CHECK: !quant.uniform<i8<-8:7>:f32, 9.987200e-01:127>
+!qalias = type !quant.uniform<i8<-8:7>:f32, 0.99872:127  >
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -22,8 +22,8 @@ func @parse() -> !qalias {
 // -----
 // Required per-layer params specified:
 //   [unsigned] storageType, expressedType, scale
-// CHECK: !quant<"uniform[u8:f32]{9.987200e-01}">
-!qalias = type !quant<"uniform[u8:f32]{0.99872}">
+// CHECK: !quant.uniform<u8:f32, 9.987200e-01>
+!qalias = type !quant.uniform<u8:f32, 0.99872>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -31,8 +31,8 @@ func @parse() -> !qalias {
 
 // -----
 // Exponential scale (-)
-// CHECK: !quant<"uniform[u8:f32]{2.000000e-02}">
-!qalias = type !quant<"uniform[u8:f32]{2.0e-2}">
+// CHECK: !quant.uniform<u8:f32, 2.000000e-02>
+!qalias = type !quant.uniform<u8:f32, 2.0e-2>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -40,8 +40,8 @@ func @parse() -> !qalias {
 
 // -----
 // Exponential scale (+)
-// CHECK: !quant<"uniform[u8:f32]{2.000000e+02}">
-!qalias = type !quant<"uniform[u8:f32]{2.0e+2}">
+// CHECK: !quant.uniform<u8:f32, 2.000000e+02>
+!qalias = type !quant.uniform<u8:f32, 2.0e+2>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -49,8 +49,8 @@ func @parse() -> !qalias {
 
 // -----
 // Storage type: i16
-// CHECK: !quant<"uniform[i16:f32]{2.000000e+02}">
-!qalias = type !quant<"uniform[i16:f32]{2.0e+2}">
+// CHECK: !quant.uniform<i16:f32, 2.000000e+02>
+!qalias = type !quant.uniform<i16:f32, 2.0e+2>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -58,8 +58,8 @@ func @parse() -> !qalias {
 
 // -----
 // Storage type: u16
-// CHECK: !quant<"uniform[u16:f32]{2.000000e+02}">
-!qalias = type !quant<"uniform[u16:f32]{2.0e+2}">
+// CHECK: !quant.uniform<u16:f32, 2.000000e+02>
+!qalias = type !quant.uniform<u16:f32, 2.0e+2>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -67,8 +67,8 @@ func @parse() -> !qalias {
 
 // -----
 // Storage type: i32
-// CHECK: !quant<"uniform[i32:f32]{2.000000e+02}">
-!qalias = type !quant<"uniform[i32:f32]{2.0e+2}">
+// CHECK: !quant.uniform<i32:f32, 2.000000e+02>
+!qalias = type !quant.uniform<i32:f32, 2.0e+2>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -76,8 +76,8 @@ func @parse() -> !qalias {
 
 // -----
 // Storage type: u32
-// CHECK: !quant<"uniform[u32:f32]{2.000000e+02}">
-!qalias = type !quant<"uniform[u32:f32]{2.0e+2}">
+// CHECK: !quant.uniform<u32:f32, 2.000000e+02>
+!qalias = type !quant.uniform<u32:f32, 2.0e+2>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -85,8 +85,8 @@ func @parse() -> !qalias {
 
 // -----
 // Expressed type: f32
-// CHECK: !quant<"uniform[u8:f32]{2.000000e+02}">
-!qalias = type !quant<"uniform[u8:f32]{2.0e+2}">
+// CHECK: !quant.uniform<u8:f32, 2.000000e+02>
+!qalias = type !quant.uniform<u8:f32, 2.0e+2>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -94,8 +94,8 @@ func @parse() -> !qalias {
 
 // -----
 // Expressed type: f16
-// CHECK: !quant<"uniform[u8:f16]{2.000000e+02}">
-!qalias = type !quant<"uniform[u8:f16]{2.0e+2}">
+// CHECK: !quant.uniform<u8:f16, 2.000000e+02>
+!qalias = type !quant.uniform<u8:f16, 2.0e+2>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -103,8 +103,8 @@ func @parse() -> !qalias {
 
 // -----
 // Expressed type: f64
-// CHECK: !quant<"uniform[u8:f64]{2.000000e+02}">
-!qalias = type !quant<"uniform[u8:f64]{2.0e+2}">
+// CHECK: !quant.uniform<u8:f64, 2.000000e+02>
+!qalias = type !quant.uniform<u8:f64, 2.0e+2>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -112,8 +112,8 @@ func @parse() -> !qalias {
 
 // -----
 // Expressed type: bf16
-// CHECK: !quant<"uniform[u8:bf16]{2.000000e+02}">
-!qalias = type !quant<"uniform[u8:bf16]{2.0e+2}">
+// CHECK: !quant.uniform<u8:bf16, 2.000000e+02>
+!qalias = type !quant.uniform<u8:bf16, 2.0e+2>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -121,8 +121,8 @@ func @parse() -> !qalias {
 
 // -----
 // Per-axis scales and zero points (affine)
-// CHECK: !quant<"uniform[u8:f32:1]{2.000000e+02:-120,9.987200e-01:127}">
-!qalias = type !quant<"uniform[u8:f32:1]{2.0e+2:-120,0.99872:127}">
+// CHECK: !quant.uniform<u8:f32:1, {2.000000e+02:-120,9.987200e-01:127}>
+!qalias = type !quant.uniform<u8:f32:1, {2.0e+2:-120,0.99872:127}>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -130,8 +130,8 @@ func @parse() -> !qalias {
 
 // -----
 // Per-axis scales and no zero points (fixedpoint)
-// CHECK: !quant<"uniform[i8:f32:1]{2.000000e+02,9.987200e-01}">
-!qalias = type !quant<"uniform[i8:f32:1]{2.0e+2,0.99872}">
+// CHECK: !quant.uniform<i8:f32:1, {2.000000e+02,9.987200e-01}>
+!qalias = type !quant.uniform<i8:f32:1, {2.0e+2,0.99872}>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias
@@ -139,8 +139,8 @@ func @parse() -> !qalias {
 
 // -----
 // Per-axis scales and zero points (mixed affine and fixedpoint)
-// CHECK: !quant<"uniform[i8:f32:1]{2.000000e+02,9.987200e-01:120}">
-!qalias = type !quant<"uniform[i8:f32:1]{2.0e+2,0.99872:120}">
+// CHECK: !quant.uniform<i8:f32:1, {2.000000e+02,9.987200e-01:120}>
+!qalias = type !quant.uniform<i8:f32:1, {2.0e+2,0.99872:120}>
 func @parse() -> !qalias {
   %0 = "foo"() : () -> !qalias
   return %0 : !qalias