[Mlir-commits] [mlir] QuantileType relax quantileType conditions and inheritance issue (PR #204793)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Jun 23 03:27:20 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir

Author: vsimion26

<details>
<summary>Changes</summary>

# Recategorize QuantileType as Storage Format, Not Quantization Scheme

## Summary

Reclassify `QuantileType` from inheriting `QuantizedType` to functioning as a pure storage type. 

## Motivation

### QuantileType is a Storage Format, Not a Quantization Scheme

After careful consideration, there was a conclusion reached that **QuantileType should not be registered as a subtype of QuantizedType**. The architectural distinction is critical:

- **QuantizedType** represents different quantization schemes (uniform, per-axis, etc.),  semantic operations that map values into a lower-precision domain
- **QuantileType** is purely a **storage format** that specifies how to interpret indices within a lookup table (LUT)

QuantileType was never meant to function as a quantization scheme on its own. Instead, its purpose is to indicate **how to interpret indices based on the given LUT**. It is an orthogonal concern to quantization semantics; it describes data organization, not mathematical transformation.

### Relaxed Type Conditions

The previous implementation restricted the LUT values to float types only. However, float types are not the only types that can exist inside a LUT, integer types are valid as well.

This PR removes the type restriction, allowing **both floating-point and integer-based LUT interpretations** to coexist, better matching actual use cases.

## Changes

- **Removed**: Incorrect inheritance of `QuantizedType` by `QuantileType`
- **Relaxed**: Type constraints to accept both float and integer LUT value types


---
Full diff: https://github.com/llvm/llvm-project/pull/204793.diff


3 Files Affected:

- (modified) mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h (+5-5) 
- (modified) mlir/lib/Dialect/Quant/IR/QuantTypes.cpp (+5-3) 
- (modified) mlir/test/Dialect/Quant/invalid-quantile-types.mlir (+2-2) 


``````````diff
diff --git a/mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h b/mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h
index 2001178d5939c..98c912024a6a7 100644
--- a/mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h
+++ b/mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h
@@ -551,13 +551,14 @@ class CalibratedQuantizedType
 /*Syntax:
 
     ```
-    quantile-type ::= `!quant.quantile` `<` type `:` type `,` `{` float-list `}`
+    quantile-type ::= `!quant.quantile` `<` type `:` type `,` `{` float-list /
+   int-list `}`
    (`,` `<` int `,` int `>`)? `>`
     ```
 
     A quantile type represents a quantile-based floating point encoding, where
-    discrete storage values are totally defined by the floating-point values
-   entries in a quantile lookup table of F8/F16/F32/F64.
+    discrete storage values are totally defined by the floating-point or integer
+   values entries in a quantile lookup table of F8/F16/F32/F64 or integer types.
 
     Optionally, explicit minimum and maximum storage values can be specified
     after the LUT as `<min:max>`.
@@ -587,8 +588,7 @@ class CalibratedQuantizedType
 */
 
 class QuantileType
-    : public Type::TypeBase<QuantileType, QuantizedType,
-                            detail::QuantileTypeStorage,
+    : public Type::TypeBase<QuantileType, Type, detail::QuantileTypeStorage,
                             mlir::QuantStorageTypeInterface::Trait> {
 public:
   using ImplType = detail::QuantileTypeStorage;
diff --git a/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp b/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp
index c150c151e1e11..adabb49aea003 100644
--- a/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp
+++ b/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp
@@ -41,7 +41,8 @@ unsigned QuantizedType::getFlags() const {
 }
 
 bool QuantizedType::classof(Type type) {
-  return llvm::isa<QuantDialect>(type.getDialect());
+  return llvm::isa<QuantDialect>(type.getDialect()) &&
+         !llvm::isa<QuantileType>(type);
 }
 
 LogicalResult
@@ -578,8 +579,9 @@ LogicalResult QuantileType::verifyInvariants(
     std::optional<int64_t> storageMin, std::optional<int64_t> storageMax) {
   if (!storageType.isIntOrFloat())
     return emitError() << "storage type must be an integer or float type";
-  if (!llvm::isa<mlir::FloatType>(quantileType))
-    return emitError() << "quantile type must be a float type";
+  if (!llvm::isa<mlir::FloatType>(quantileType) &&
+      !llvm::isa<mlir::IntegerType>(quantileType))
+    return emitError() << "quantile type must be a float or integer type";
   if (quantiles.empty())
     return emitError() << "quantile values must not be empty";
   if (storageMin.has_value() != storageMax.has_value())
diff --git a/mlir/test/Dialect/Quant/invalid-quantile-types.mlir b/mlir/test/Dialect/Quant/invalid-quantile-types.mlir
index faf16d01a9cd5..4a7703fd0e553 100644
--- a/mlir/test/Dialect/Quant/invalid-quantile-types.mlir
+++ b/mlir/test/Dialect/Quant/invalid-quantile-types.mlir
@@ -11,8 +11,8 @@ func.func private @invalid_storage_type() -> !quant.quantile<tensor<1xf32>:f32,
 // -----
 
 // Quantile (expressed) type must be a float.
-// expected-error @+1 {{quantile type must be a float type}}
-func.func private @invalid_quantile_type() -> !quant.quantile<ui4:i8, {1.0, 0.0, -1.0}>
+// expected-error @+1 {{quantile type must be a float or integer type}}
+func.func private @invalid_quantile_type() -> !quant.quantile<ui4:tensor<1xf32>, {1.0, 0.0, -1.0}>
 
 // -----
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/204793


More information about the Mlir-commits mailing list