)]}'
{
  "commit": "a6788b52468fb1bf661ce76f95ad92d0050bd35e",
  "tree": "a3f422e085447c456fbacd58fef17b6390cc60a4",
  "parents": [
    "f8a0599d761e4283b3877f0bf4043e01722dc448"
  ],
  "author": {
    "name": "Hanumanth",
    "email": "hhanuman@mathworks.com",
    "time": "Mon Oct 27 14:43:18 2025 -0400"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Mon Oct 27 11:43:18 2025 -0700"
  },
  "message": "[mlir][tensor] Fix runtime verification for `tensor.extract_slice` when size dimension value is 0 (#164878)\n\nPreviously, the runtime verification pass would insert assertion\nstatements with conditions that always evaluate to false for\nsemantically valid `tensor.extract_slice` operations where one of the\ndimensions had a size of 0.\n\nThe `tensor.extract_slice` runtime verification logic was\nunconditionally generating checks for the position of the last element\n(`offset + (size - 1) * stride`). When `size` is 0, this causes the\nassertion condition to always be false, leading to runtime failures even\nthough the operation is semantically valid.\n\nThis patch fixes the issue by making the `lastPos` check conditional.\nThe offset is always verified, but the endpoint check is only performed\nwhen `size \u003e 0` to avoid generating spurious assert statements.\n\nThis issue was discovered through LiteRT model, where a dynamic shape\ncalculation resulted in a zero-sized dimension being passed to\n`tensor.extract_slice`.\n\nThe following is a simplified IR snippet from the model. After running\nthe runtime verification pass, an assertion that always fails is\ngenerated because the SSA value `%3` becomes 0.\n\n```mlir\nfunc.func @simple_repro_from_liteRT_model(%arg0: tensor\u003c10x4x1xf32\u003e) -\u003e tensor\u003c?x?x?xf32\u003e {\n  %cst \u003d arith.constant dense\u003c0\u003e : tensor\u003c1xi32\u003e\n  %cst_0 \u003d arith.constant dense\u003c-1\u003e : tensor\u003c2xi32\u003e\n  %c-1 \u003d arith.constant -1 : index\n  %c0 \u003d arith.constant 0 : index\n  %c10 \u003d arith.constant 10 : index\n  %c1 \u003d arith.constant 1 : index\n  %c4 \u003d arith.constant 4 : index\n  %c2 \u003d arith.constant 2 : index\n  %0 \u003d tensor.empty() : tensor\u003c3xi32\u003e\n  %inserted_slice \u003d tensor.insert_slice %cst into %0[0] [1] [1] : tensor\u003c1xi32\u003e into tensor\u003c3xi32\u003e\n  %inserted_slice_1 \u003d tensor.insert_slice %cst_0 into %inserted_slice[1] [2] [1] : tensor\u003c2xi32\u003e into tensor\u003c3xi32\u003e\n  %extracted \u003d tensor.extract %inserted_slice_1[%c0] : tensor\u003c3xi32\u003e\n  %1 \u003d index.casts %extracted : i32 to index\n  %2 \u003d arith.cmpi eq, %1, %c-1 : index\n  %3 \u003d arith.select %2, %c10, %1 : index\n  %extracted_2 \u003d tensor.extract %inserted_slice_1[%c1] : tensor\u003c3xi32\u003e\n  %4 \u003d index.casts %extracted_2 : i32 to index\n  %5 \u003d arith.cmpi eq, %4, %c-1 : index\n  %6 \u003d arith.select %5, %c4, %4 : index\n  %extracted_3 \u003d tensor.extract %inserted_slice_1[%c2] : tensor\u003c3xi32\u003e\n  %7 \u003d index.casts %extracted_3 : i32 to index\n  %8 \u003d arith.cmpi eq, %7, %c-1 : index\n  %9 \u003d arith.select %8, %c1, %7 : index\n  %extracted_slice \u003d tensor.extract_slice %arg0[0, 0, 0] [%3, %6, %9] [1, 1, 1] : tensor\u003c10x4x1xf32\u003e to tensor\u003c?x?x?xf32\u003e\n  return %extracted_slice : tensor\u003c?x?x?xf32\u003e\n}\n```\n\nThe issue can be reproduced more simply with the following test case,\nwhere `dim_0` is `0`. When the runtime verification pass is applied to\nthis code with `dim_0 \u003d 0`, it generates an assertion that will always\nfail at runtime.\n\n```mlir\nfunc.func @extract_slice_zero_size_dim(%arg0: tensor\u003c10x4x1xf32\u003e,\n                                      %dim_0: index,\n                                      %dim_1: index,\n                                      %dim_2: index) {\n  %slice \u003d tensor.extract_slice %arg0[0, 0, 0] [%dim_0, %dim_1, %dim_2] [1, 1, 1]\n    : tensor\u003c10x4x1xf32\u003e to tensor\u003c?x?x?xf32\u003e\n  return\n}\n\nfunc.func @test_zero_size_extraction() {\n  %input \u003d arith.constant dense\u003c1.0\u003e : tensor\u003c10x4x1xf32\u003e\n  // Define slice dimensions: 0x4x1 (zero-size in first dimension)\n  %dim_0 \u003d arith.constant 0 : index\n  %dim_1 \u003d arith.constant 4 : index\n  %dim_2 \u003d arith.constant 1 : index\n  func.call @extract_slice_zero_size_dim(%input, %dim_0, %dim_1, %dim_2)\n    : (tensor\u003c10x4x1xf32\u003e, index, index, index) -\u003e ()\n  return\n}\n```\n\nP.S. We probably have a similar issue with `memref.subview`. I will\ncheck this and send a separate PR for the issue.\n\n---------\n\nCo-authored-by: Hanumanth Hanumantharayappa \u003chhanuman@ah-hhanuman-l.dhcp.mathworks.com\u003e",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "c031118606823fe0ef70f3fb7e49a092c8414f48",
      "old_mode": 33188,
      "old_path": "mlir/lib/Dialect/Tensor/Transforms/RuntimeOpVerification.cpp",
      "new_id": "753cb95b1c90656cf5ac2c0db19a094873132c2e",
      "new_mode": 33188,
      "new_path": "mlir/lib/Dialect/Tensor/Transforms/RuntimeOpVerification.cpp"
    },
    {
      "type": "modify",
      "old_id": "0c7c4a6cb2d6f7c8c3ed031ed8c2029967ed76ab",
      "old_mode": 33188,
      "old_path": "mlir/test/Integration/Dialect/Tensor/extract_slice-runtime-verification.mlir",
      "new_id": "a77fa310a369937a9f5ec06813a106bda6098804",
      "new_mode": 33188,
      "new_path": "mlir/test/Integration/Dialect/Tensor/extract_slice-runtime-verification.mlir"
    }
  ]
}
