[Mlir-commits] [mlir] 34b6e1c - [mlir][arith] Reject signful integer element types in `arith.constant` (#204937)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Jun 23 07:38:24 PDT 2026


Author: Chirag Wattamwar
Date: 2026-06-23T16:38:19+02:00
New Revision: 34b6e1c3b07d2d18b3112841992378b1057d87cc

URL: https://github.com/llvm/llvm-project/commit/34b6e1c3b07d2d18b3112841992378b1057d87cc
DIFF: https://github.com/llvm/llvm-project/commit/34b6e1c3b07d2d18b3112841992378b1057d87cc.diff

LOG: [mlir][arith] Reject signful integer element types in `arith.constant` (#204937)

Update arith.constant verification to reject integer constants with
signed and unsigned element types including shaped constants like
tensors and vectors, as the arith dialect does not support
signed/unsigned types.

This incidentally address cases where further lowering would crash (e.g.
SPIR-V constant lowering used IntegerAttr::getInt() on an unsigned
integer attribute from tensor<2xui8>)

Fixes #204911

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
    mlir/lib/Dialect/Arith/IR/ArithOps.cpp
    mlir/test/Dialect/Arith/invalid.mlir
    mlir/test/Dialect/Tosa/tosa-arith-const-to-tosa-const.mlir
    mlir/test/Dialect/common_folders.mlir
    mlir/test/lib/Dialect/Test/TestOps.td

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td b/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
index 1f8b07aed3f0d..423948c8734af 100644
--- a/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
+++ b/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
@@ -244,12 +244,8 @@ def Arith_ConstantOp : Op<Arith_Dialect, "constant",
   }];
 
   let arguments = (ins TypedAttrInterface:$value);
-  // TODO: Disallow arith.constant to return anything other than a signless
-  // integer or float like. Downstream users of Arith should only be
-  // working with signless integers, floats, or vectors/tensors thereof.
-  // However, it is necessary to allow arith.constant to return vectors/tensors
-  // of strings and signed/unsigned integers (for now) as an artefact of
-  // splitting the Standard dialect.
+  // Keep this broad so the custom verifier can produce arith.constant-specific
+  // diagnostics after checking that the value and result types match.
   let results = (outs /*SignlessIntegerOrIndexOrFloatLike*/AnyType:$result);
 
   let extraClassDeclaration = [{

diff  --git a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
index dc3887c3e0b0e..397fa28227831 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
@@ -231,8 +231,8 @@ void arith::ConstantOp::getAsmResultNames(
 LogicalResult arith::ConstantOp::verify() {
   auto type = getType();
   // Integer values must be signless.
-  if (llvm::isa<IntegerType>(type) &&
-      !llvm::cast<IntegerType>(type).isSignless())
+  if (auto intType = dyn_cast<IntegerType>(getElementTypeOrSelf(type));
+      intType && !intType.isSignless())
     return emitOpError("integer return type must be signless");
   // Any float or elements attribute are acceptable.
   if (!llvm::isa<IntegerAttr, FloatAttr, ElementsAttr>(getValue())) {

diff  --git a/mlir/test/Dialect/Arith/invalid.mlir b/mlir/test/Dialect/Arith/invalid.mlir
index 421dac9cfee15..49f55e855663d 100644
--- a/mlir/test/Dialect/Arith/invalid.mlir
+++ b/mlir/test/Dialect/Arith/invalid.mlir
@@ -32,6 +32,14 @@ func.func @non_signless_constant() {
 
 // -----
 
+func.func @non_signless_tensor_constant() {
+  // expected-error @+1 {{'arith.constant' op integer return type must be signless}}
+  %0 = arith.constant dense<[10, 20]> : tensor<2xui8>
+  return
+}
+
+// -----
+
 func.func @complex_constant_wrong_attribute_type() {
   // expected-error @+1 {{'arith.constant' op failed to verify that all of {value, result} have same type}}
   %0 = "arith.constant" () {value = 1.0 : f32} : () -> complex<f32>
@@ -48,6 +56,14 @@ func.func @non_signless_constant() {
 
 // -----
 
+func.func @non_signless_vector_constant() {
+  // expected-error @+1 {{'arith.constant' op integer return type must be signless}}
+  %0 = arith.constant dense<[0, 1]> : vector<2xsi32>
+  return
+}
+
+// -----
+
 func.func @bitcast_
diff erent_bit_widths(%arg : f16) -> f32 {
   // expected-error at +1 {{are cast incompatible}}
   %res = arith.bitcast %arg : f16 to f32

diff  --git a/mlir/test/Dialect/Tosa/tosa-arith-const-to-tosa-const.mlir b/mlir/test/Dialect/Tosa/tosa-arith-const-to-tosa-const.mlir
index fc2d77ef375ec..79219510a239f 100644
--- a/mlir/test/Dialect/Tosa/tosa-arith-const-to-tosa-const.mlir
+++ b/mlir/test/Dialect/Tosa/tosa-arith-const-to-tosa-const.mlir
@@ -65,14 +65,6 @@ func.func @rewrite_resource_tensor() -> tensor<4xf32> {
 
 // -----
 
-// CHECK-LABEL: func.func @rewrite_quant_tensor
-// CHECK: %[[CST:.*]] = "tosa.const"() <{values = dense<[10, 20]> : tensor<2xui8>}> : () -> tensor<2xui8>
-func.func @rewrite_quant_tensor() -> tensor<2xui8> {
-  %c = arith.constant dense<[10, 20]> : tensor<2xui8>
-  return %c : tensor<2xui8>
-}
-
-// -----
 
 // CHECK-LABEL: func.func @rewrite_quant_uniform_tensor
 // CHECK: %[[CST:.*]] = "tosa.const"() <{values = dense<["10", "20"]> : tensor<2x!quant.uniform<i8:f32, 5.000000e-01>>}> : () -> tensor<2x!quant.uniform<i8:f32, 5.000000e-01>>

diff  --git a/mlir/test/Dialect/common_folders.mlir b/mlir/test/Dialect/common_folders.mlir
index 92598b4937552..9e38c1479e2e7 100644
--- a/mlir/test/Dialect/common_folders.mlir
+++ b/mlir/test/Dialect/common_folders.mlir
@@ -1,12 +1,12 @@
 // RUN: mlir-opt %s --test-fold-type-converting-op --split-input-file | FileCheck %s
 
-// CHECK-LABEL: @test_fold_unary_op_f32_to_si32(
-func.func @test_fold_unary_op_f32_to_si32() -> tensor<4x2xsi32> {
-  // CHECK-NEXT: %[[POSITIVE_ONE:.*]] = arith.constant dense<1> : tensor<4x2xsi32>
-  // CHECK-NEXT: return %[[POSITIVE_ONE]] : tensor<4x2xsi32>
+// CHECK-LABEL: @test_fold_unary_op_f32_to_i32(
+func.func @test_fold_unary_op_f32_to_i32() -> tensor<4x2xi32> {
+  // CHECK-NEXT: %[[POSITIVE_ONE:.*]] = arith.constant dense<1> : tensor<4x2xi32>
+  // CHECK-NEXT: return %[[POSITIVE_ONE]] : tensor<4x2xi32>
   %operand = arith.constant dense<5.1> : tensor<4x2xf32>
-  %sign = test.sign %operand : (tensor<4x2xf32>) -> tensor<4x2xsi32>
-  return %sign : tensor<4x2xsi32>
+  %sign = test.sign %operand : (tensor<4x2xf32>) -> tensor<4x2xi32>
+  return %sign : tensor<4x2xi32>
 }
 
 // -----

diff  --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td
index df321bd5feabc..31c19487075d8 100644
--- a/mlir/test/lib/Dialect/Test/TestOps.td
+++ b/mlir/test/lib/Dialect/Test/TestOps.td
@@ -1358,10 +1358,10 @@ def OpQ : TEST_Op<"op_q"> {
   let results = (outs AnyType);
 }
 
-// Test constant-folding a pattern that maps `(F32) -> SI32`.
+// Test constant-folding a pattern that maps `(F32) -> I32`.
 def SignOp : TEST_Op<"sign", [SameOperandsAndResultShape]> {
   let arguments = (ins RankedTensorOf<[F32]>:$operand);
-  let results = (outs RankedTensorOf<[SI32]>:$result);
+  let results = (outs RankedTensorOf<[I32]>:$result);
 
   let assemblyFormat = [{
     $operand attr-dict `:` functional-type(operands, results)


        


More information about the Mlir-commits mailing list