[Mlir-commits] [mlir] 139e2fb - [mlir][tosa]: Add Binary Shape Ops folders (#178877)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Feb 3 03:32:49 PST 2026


Author: Udaya Ranga
Date: 2026-02-03T11:32:44Z
New Revision: 139e2fb60217a9cbdb68f9efad32da611b957c30

URL: https://github.com/llvm/llvm-project/commit/139e2fb60217a9cbdb68f9efad32da611b957c30
DIFF: https://github.com/llvm/llvm-project/commit/139e2fb60217a9cbdb68f9efad32da611b957c30.diff

LOG: [mlir][tosa]: Add Binary Shape Ops folders (#178877)

* SUB_SHAPE
* MUL_SHAPE
* DIV_CEIL_SHAPE
* DIV_FLOOR_SHAPE
* MOD_SHAPE


Change-Id: I12500bbc05c62730e0dc9cc8d3f20b02845d407e

Signed-off-by: Udaya Ranga <udaya.ranga at arm.com>

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/Tosa/IR/TosaShapeOps.td
    mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp
    mlir/test/Dialect/Tosa/constant_folding.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaShapeOps.td b/mlir/include/mlir/Dialect/Tosa/IR/TosaShapeOps.td
index 57fd1d2d20aa8..104f2741e5678 100644
--- a/mlir/include/mlir/Dialect/Tosa/IR/TosaShapeOps.td
+++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaShapeOps.td
@@ -159,6 +159,8 @@ def Tosa_DivCeilShapeOp : Tosa_ElementwiseShapeOp<"div_ceil_shape", [Pure]> {
   );
 
   let results = (outs Tosa_Shape:$output);
+
+  let hasFolder = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -177,6 +179,8 @@ def Tosa_DivFloorShapeOp : Tosa_ElementwiseShapeOp<"div_floor_shape", [Pure]> {
   );
 
   let results = (outs Tosa_Shape:$output);
+
+  let hasFolder = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -282,6 +286,8 @@ def Tosa_ModShapeOp : Tosa_ElementwiseShapeOp<"mod_shape", [Pure]> {
   );
 
   let results = (outs Tosa_Shape:$output);
+
+  let hasFolder = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -300,6 +306,8 @@ def Tosa_MulShapeOp : Tosa_ElementwiseShapeOp<"mul_shape", [Pure]> {
   );
 
   let results = (outs Tosa_Shape:$output);
+
+  let hasFolder = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -339,6 +347,8 @@ def Tosa_SubShapeOp : Tosa_ElementwiseShapeOp<"sub_shape", [Pure]> {
   );
 
   let results = (outs Tosa_Shape:$output);
+
+  let hasFolder = 1;
 }
 
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp
index 07a0b6742d48a..ed1584f93a367 100644
--- a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp
+++ b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp
@@ -986,7 +986,7 @@ binaryFolder(DenseElementsAttr lhs, DenseElementsAttr rhs, ShapedType returnTy,
 
   return {};
 }
-struct FoldAddAdaptor {
+struct AddFoldAdaptor {
   static FailureOr<APInt> fold(const APInt &lhs, const APInt &rhs,
                                const bool isUnsigned) {
     bool overflow;
@@ -1002,7 +1002,7 @@ struct FoldAddAdaptor {
   }
 };
 
-struct FoldSubAdaptor {
+struct SubFoldAdaptor {
   static FailureOr<APInt> fold(const APInt &lhs, const APInt &rhs,
                                const bool isUnsigned) {
     bool overflow;
@@ -1018,6 +1018,104 @@ struct FoldSubAdaptor {
   }
 };
 
+struct MulFoldAdaptor {
+  static FailureOr<APInt> fold(const APInt &lhs, const APInt &rhs,
+                               const bool isUnsigned) {
+
+    const unsigned originalWidth = lhs.getBitWidth();
+
+    // Check same type
+    if (lhs.getBitWidth() != rhs.getBitWidth()) {
+      return failure();
+    }
+
+    // If either is `0`
+    if (lhs == 0 || rhs == 0)
+      return APInt::getZero(originalWidth);
+
+    bool overflow = false;
+    APInt const result =
+        isUnsigned ? lhs.umul_ov(rhs, overflow) : lhs.smul_ov(rhs, overflow);
+
+    if (overflow)
+      return failure();
+
+    return result.trunc(originalWidth);
+  }
+
+  static FailureOr<APFloat> fold(const APFloat &lhs, const APFloat &rhs) {
+    return lhs * rhs;
+  }
+};
+
+static bool signsDiffer(const APInt &a, const APInt &b) {
+  return a.isNegative() != b.isNegative();
+}
+
+template <bool Ceil>
+struct DivFoldAdaptor {
+  static FailureOr<APInt> fold(const APInt &lhs, const APInt &rhs,
+                               bool isUnsigned) {
+    if (lhs.getBitWidth() != rhs.getBitWidth())
+      return failure();
+    if (rhs.isZero())
+      return failure();
+
+    if (isUnsigned) {
+      APInt q{};
+      APInt r{};
+      APInt::udivrem(lhs, rhs, q, r);
+      if (!r.isZero() && Ceil) {
+        return q + 1;
+      }
+      return q;
+    }
+
+    // Signed: start from trunc-toward-zero, then adjust to ceil.
+    bool overflow{false};
+    APInt const q = lhs.sdiv_ov(rhs, overflow);
+    if (overflow)
+      return failure();
+    APInt const r = lhs.srem(rhs);
+
+    if (Ceil && !r.isZero() && !signsDiffer(lhs, rhs)) {
+      // Same sign => exact quotient is positive; trunc is below ceil =>
+      // increment q.
+      return q + 1;
+    }
+    return q;
+  }
+
+  static FailureOr<APFloat> fold(const APFloat &lhs, const APFloat &rhs) {
+    return lhs / rhs;
+  }
+};
+
+struct ModFoldAdaptor {
+  static FailureOr<APInt> fold(const APInt &lhs, const APInt &rhs,
+                               bool isUnsigned) {
+    if (lhs.getBitWidth() != rhs.getBitWidth())
+      return failure();
+    if (lhs.isNegative() || (!rhs.isStrictlyPositive()))
+      return failure();
+
+    if (isUnsigned) {
+      return lhs.urem(rhs);
+    }
+
+    return lhs.srem(rhs);
+  }
+
+  static FailureOr<APFloat> fold(const APFloat &lhs, const APFloat &rhs) {
+    auto t = lhs;
+    auto const r = t.mod(rhs);
+    if (llvm::APFloatBase::opStatus::opOK == r) {
+      return t;
+    }
+    return failure();
+  }
+};
+
 struct FoldGreaterAdaptor {
   static FailureOr<APInt> fold(const APInt &lhs, const APInt &rhs,
                                const bool isUnsigned) {
@@ -1097,7 +1195,7 @@ OpFoldResult AddOp::fold(FoldAdaptor adaptor) {
   if (!lhsAttr || !rhsAttr)
     return {};
 
-  return binaryFolder<FoldAddAdaptor>(lhsAttr, rhsAttr, resultTy);
+  return binaryFolder<AddFoldAdaptor>(lhsAttr, rhsAttr, resultTy);
 }
 
 OpFoldResult ArgMaxOp::fold(FoldAdaptor adaptor) {
@@ -1149,8 +1247,11 @@ OpFoldResult IntDivOp::fold(FoldAdaptor adaptor) {
     APInt l = lhsAttr.getSplatValue<APInt>();
     APInt r = rhsAttr.getSplatValue<APInt>();
     if (!r.isZero()) {
-      APInt result = l.sdiv(r);
-      return DenseElementsAttr::get(resultTy, result);
+      auto const result =
+          DivFoldAdaptor</*Ceil*/ false>::fold(l, r, /*isUnsigned*/ false);
+      if (failed(result))
+        return {};
+      return DenseElementsAttr::get(resultTy, result.value());
     }
   }
 
@@ -1162,7 +1263,11 @@ namespace {
 // return nullopt if result is not in range of int32_t when shift > 0
 std::optional<APInt> mulInt(APInt lhs, APInt rhs, int32_t shift,
                             unsigned bitwidth) {
-  APInt result = lhs.sext(64) * rhs.sext(64);
+  bool overflow = false;
+  APInt result = lhs.sext(64).smul_ov(rhs.sext(64), overflow);
+
+  if (overflow)
+    return std::nullopt;
 
   if (shift > 0) {
     auto round = APInt(64, 1) << (shift - 1);
@@ -1278,7 +1383,7 @@ OpFoldResult SubOp::fold(FoldAdaptor adaptor) {
   if (!lhsAttr || !rhsAttr)
     return {};
 
-  return binaryFolder<FoldSubAdaptor>(lhsAttr, rhsAttr, resultTy);
+  return binaryFolder<SubFoldAdaptor>(lhsAttr, rhsAttr, resultTy);
 }
 
 OpFoldResult GreaterOp::fold(FoldAdaptor adaptor) {
@@ -1750,18 +1855,19 @@ OpFoldResult tosa::ReciprocalOp::fold(FoldAdaptor adaptor) {
   return {};
 }
 
-OpFoldResult tosa::AddShapeOp::fold(FoldAdaptor adaptor) {
+template <typename Op, typename OpFoldAdaptor>
+OpFoldResult binaryFold(Op *op) {
   auto input1ConstShape =
-      dyn_cast<tosa::ConstShapeOp>(getInput1().getDefiningOp());
+      dyn_cast<tosa::ConstShapeOp>(op->getInput1().getDefiningOp());
   auto input2ConstShape =
-      dyn_cast<tosa::ConstShapeOp>(getInput2().getDefiningOp());
+      dyn_cast<tosa::ConstShapeOp>(op->getInput2().getDefiningOp());
   if (!input1ConstShape || !input2ConstShape)
     return {};
 
   const auto input1Attr = cast<DenseElementsAttr>(input1ConstShape.getValues());
   const auto input2Attr = cast<DenseElementsAttr>(input2ConstShape.getValues());
 
-  return binaryFolder<FoldAddAdaptor>(
+  return binaryFolder<OpFoldAdaptor>(
       input1Attr, input2Attr, input1Attr.getType(), /*foldDenseValues=*/true);
 }
 
@@ -1779,3 +1885,27 @@ OpFoldResult tosa::DimOp::fold(FoldAdaptor adaptor) {
       RankedTensorType::get(/*rank=*/1, builder.getIndexType());
   return DenseElementsAttr::get(resultAttrTy, dimSize);
 }
+
+OpFoldResult tosa::AddShapeOp::fold(FoldAdaptor adaptor) {
+  return binaryFold<AddShapeOp, AddFoldAdaptor>(this);
+}
+
+OpFoldResult tosa::SubShapeOp::fold(FoldAdaptor adaptor) {
+  return binaryFold<SubShapeOp, SubFoldAdaptor>(this);
+}
+
+OpFoldResult tosa::MulShapeOp::fold(FoldAdaptor adaptor) {
+  return binaryFold<MulShapeOp, MulFoldAdaptor>(this);
+}
+
+OpFoldResult tosa::DivCeilShapeOp::fold(FoldAdaptor adaptor) {
+  return binaryFold<DivCeilShapeOp, DivFoldAdaptor</*Ceil*/ true>>(this);
+}
+
+OpFoldResult tosa::DivFloorShapeOp::fold(FoldAdaptor adaptor) {
+  return binaryFold<DivFloorShapeOp, DivFoldAdaptor</*Ceil*/ false>>(this);
+}
+
+OpFoldResult tosa::ModShapeOp::fold(FoldAdaptor adaptor) {
+  return binaryFold<ModShapeOp, ModFoldAdaptor>(this);
+}

diff  --git a/mlir/test/Dialect/Tosa/constant_folding.mlir b/mlir/test/Dialect/Tosa/constant_folding.mlir
index 4cb9a46e5d049..a8bcb9d52f000 100644
--- a/mlir/test/Dialect/Tosa/constant_folding.mlir
+++ b/mlir/test/Dialect/Tosa/constant_folding.mlir
@@ -695,6 +695,17 @@ func.func @test_fold_dim(%arg0: tensor<6xi32>) -> !tosa.shape<1> {
 
 // -----
 
+// CHECK-LABEL: @test_fold_sub_shape
+// CHECK: tosa.const_shape  {values = dense<[2, 4, 6, 8, 10, 12]> : tensor<6xindex>} : () -> !tosa.shape<6>
+func.func @test_fold_sub_shape() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[12, 22, 32, 42, 52, 62]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[10, 18, 26, 34, 42, 50]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.sub_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
 // CHECK-LABEL: @test_no_fold_dim_unranked_input
 // CHECK: tosa.dim
 func.func @test_no_fold_dim_unranked_input(%arg0: tensor<*xi32>) -> !tosa.shape<1> {
@@ -704,9 +715,163 @@ func.func @test_no_fold_dim_unranked_input(%arg0: tensor<*xi32>) -> !tosa.shape<
 
 // -----
 
+// CHECK-LABEL: @test_no_fold_sub_shape_positive_overflow
+// CHECK: tosa.sub_shape
+func.func @test_no_fold_sub_shape_positive_overflow() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[1, 2, 3, 4, 5, 9223372036854775807]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[1, 2, 3, 4, 5, -1]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.sub_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
 // CHECK-LABEL: @test_no_fold_dim_dynamic
 // CHECK: tosa.dim
 func.func @test_no_fold_dim_dynamic(%arg0: tensor<4x?xi32>) -> !tosa.shape<1> {
   %dim = tosa.dim %arg0 {axis = 1 : i32} : (tensor<4x?xi32>) -> !tosa.shape<1>
   return %dim : !tosa.shape<1>
 }
+
+// -----
+
+// CHECK-LABEL: @test_no_fold_sub_shape_negative_overflow
+// CHECK: tosa.sub_shape
+func.func @test_no_fold_sub_shape_negative_overflow() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[1, 2, 3, 4, 5, -9223372036854775808]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[1, 2, 3, 4, 5, 1]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.sub_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
+// CHECK-LABEL: @test_fold_mul_shape
+// CHECK: tosa.const_shape  {values = dense<[2, 4, 6, 8, 10, 12]> : tensor<6xindex>} : () -> !tosa.shape<6>
+func.func @test_fold_mul_shape() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[2, 2, 3, 4, 2, 3]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[1, 2, 2, 2, 5, 4]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.mul_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
+// CHECK-LABEL: @test_no_fold_mul_shape_positive_overflow
+// CHECK: tosa.mul_shape
+func.func @test_no_fold_mul_shape_positive_overflow() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[1, 2, 3, 4, 5, 9223372036854775807]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[1, 2, 3, 4, 5, 2]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.mul_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
+// CHECK-LABEL: @test_no_fold_mul_shape_negative_overflow
+// CHECK: tosa.mul_shape
+func.func @test_no_fold_mul_shape_negative_overflow() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[1, 2, 3, 4, 5, -9223372036854775808]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[1, 2, 3, 4, 5, 2]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.mul_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
+// CHECK-LABEL: @test_fold_div_ceil_shape
+// CHECK: tosa.const_shape  {values = dense<[2, 4, 6, 8, 10, 12]> : tensor<6xindex>} : () -> !tosa.shape<6>
+func.func @test_fold_div_ceil_shape() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[2, 7, 11, 22, 47, 46]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[1, 2, 2, 3, 5, 4]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.div_ceil_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
+// CHECK-LABEL: @test_no_fold_div_ceil_shape_positive_overflow
+// CHECK: tosa.div_ceil_shape
+func.func @test_no_fold_div_ceil_shape_positive_overflow() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[2, 7, 11, 22, 47, 9223372036854775807]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[1, 2, 2, 3, 5, 0]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.div_ceil_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
+// CHECK-LABEL: @test_no_fold_div_ceil_shape_negative_overflow
+// CHECK: tosa.div_ceil_shape
+func.func @test_no_fold_div_ceil_shape_negative_overflow() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[2, 7, 11, 22, 47, -9223372036854775808]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[1, 2, 2, 3, 5, 0]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.div_ceil_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
+// CHECK-LABEL: @test_fold_div_floor_shape
+// CHECK: tosa.const_shape  {values = dense<[2, 3, 5, 7, 9, 11]> : tensor<6xindex>} : () -> !tosa.shape<6>
+func.func @test_fold_div_floor_shape() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[2, 7, 11, 22, 47, 46]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[1, 2, 2, 3, 5, 4]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.div_floor_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
+// CHECK-LABEL: @test_no_fold_div_floor_shape_positive_overflow
+// CHECK: tosa.div_floor_shape
+func.func @test_no_fold_div_floor_shape_positive_overflow() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[2, 7, 11, 22, 47, 9223372036854775807]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[1, 2, 2, 3, 5, 0]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.div_floor_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
+// CHECK-LABEL: @test_no_fold_div_floor_shape_negative_overflow
+// CHECK: tosa.div_floor_shape
+func.func @test_no_fold_div_floor_shape_negative_overflow() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[2, 7, 11, 22, 47, -9223372036854775808]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[1, 2, 2, 3, 5, 0]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.div_floor_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
+// CHECK-LABEL: @test_fold_mod_shape
+// CHECK: tosa.const_shape  {values = dense<[2, 1, 5, 7, 9, 11]> : tensor<6xindex>} : () -> !tosa.shape<6>
+func.func @test_fold_mod_shape() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[24, 7, 65, 33, 39, 39]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[11, 2, 12, 13, 15, 14]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.mod_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
+// CHECK-LABEL: @test_no_fold_mod_shape_positive_overflow
+// CHECK: tosa.mod_shape
+func.func @test_no_fold_mod_shape_positive_overflow() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[24, 7, 65, 33, 39, 9223372036854775807]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[11, 2, 12, 13, 15, 0]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.mod_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}
+
+// -----
+
+// CHECK-LABEL: @test_no_fold_mod_shape_negative_overflow
+// CHECK: tosa.mod_shape
+func.func @test_no_fold_mod_shape_negative_overflow() -> !tosa.shape<6> {
+  %a = tosa.const_shape {values = dense<[24, 7, 65, 33, 39, -9223372036854775808]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %b = tosa.const_shape {values = dense<[11, 2, 12, 13, 15, 0]> : tensor<6xindex>} : () -> !tosa.shape<6>
+  %c = tosa.mod_shape %a, %b : (!tosa.shape<6>, !tosa.shape<6>) -> !tosa.shape<6>
+  return %c : !tosa.shape<6>
+}


        


More information about the Mlir-commits mailing list