)]}'
{
  "commit": "6971dfb7570b203ef0bd6544f78b06f4ec7629e7",
  "tree": "cea20b7587bd52ba6d8da2599a348ad796a73ae7",
  "parents": [
    "4576683cfe93ff25ea7cdec6c3daefc3ad7825bf"
  ],
  "author": {
    "name": "Christopher McGirr",
    "email": "mcgirr@roofline.ai",
    "time": "Mon Jun 22 11:17:01 2026 +0200"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Mon Jun 22 11:17:01 2026 +0200"
  },
  "message": "[Codegen][GlobalOpt] Detach non-splat constant inits (#24605)\n\nA constant used directly as the `outs` (init/destination) of a\n`linalg.matmul` or convolution e.g. a fully-connected/conv bias imported\nfrom TFLite via TOSA survives into dispatch formation. It is then cloned\ninto the workgroup on the written (output) side and bufferizes as a\nread-only global, which fails workgroup-distribution verification with\nthe following error:\n\n```\n\u0027linalg.generic\u0027 op write affecting operations on global resources are restricted to workgroup distributed contexts\n\u0027func.func\u0027 op failed on workgroup distribution verification\n```\n\nThis kind of IR was seen in TFLite -\u003e TOSA conversion flows and and the\nIR below is an example of that:\n\n```mlir\nutil.func public @main(%a: tensor\u003c1x1xf32\u003e, %w: tensor\u003c1x9xf32\u003e) -\u003e tensor\u003c1x9xf32\u003e {\n  %bias \u003d arith.constant dense\u003c[[1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 4.0, 4.0, 5.0]]\u003e : tensor\u003c1x9xf32\u003e\n  %0 \u003d linalg.matmul ins(%a, %w : tensor\u003c1x1xf32\u003e, tensor\u003c1x9xf32\u003e)\n                     outs(%bias : tensor\u003c1x9xf32\u003e) -\u003e tensor\u003c1x9xf32\u003e\n  util.return %0 : tensor\u003c1x9xf32\u003e\n}\n```\n\nThe chosen solution is to use is the `DetachElementwiseFromNamedOps`\npattern which exists to keep non-writable inits out of dispatches. It\nonly covers two of our three relevant cases. The pass will\n1. Take a non-const init and detach it into a zero-fill plus a trailing\nadd\n2. Take a splat constant init and convert it to a fill.\n\nOur use-case of a non-splat constant init would not be handled. Here we\nextend the elementwise detach pattern so a non-splat constant init is\ndetached the same way a computed init is. A fresh zero-fill is created\nand the constant is added back as a read-only input. This form of IR can\nbe then handled by codegen.\n\nAfter the fix the reproducer compiles and the bias survives read-only:\n\n```\n%bias \u003d arith.constant ... : tensor\u003c1x9xf32\u003e\n%z  \u003d linalg.fill ins(%c0 : f32) outs(%empty : tensor\u003c1x9xf32\u003e) -\u003e tensor\u003c1x9xf32\u003e\n%mm \u003d linalg.matmul ins(%a, %w) outs(%z) -\u003e tensor\u003c1x9xf32\u003e\n%0  \u003d linalg.generic ins(%mm, %bias) outs(%z) { ... }   // %mm + %bias\n```\n\n---\n\n_Code Examples and Tests Assisted-by Claude_",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "24648f6727e6698bb74b7abe44819e041c88ff93",
      "old_mode": 33188,
      "old_path": "compiler/src/iree/compiler/GlobalOptimization/DetachElementwiseFromNamedOps.cpp",
      "new_id": "aa695f95cfd2618c50078b13bf11ec4c7a821e82",
      "new_mode": 33188,
      "new_path": "compiler/src/iree/compiler/GlobalOptimization/DetachElementwiseFromNamedOps.cpp"
    },
    {
      "type": "modify",
      "old_id": "870e3518637e9b79a117bb0dea2db8ff96b32c1e",
      "old_mode": 33188,
      "old_path": "compiler/src/iree/compiler/GlobalOptimization/test/detach_elementwise_from_named_ops.mlir",
      "new_id": "7075e0e9c61ce76f388c22950d8f3ac5d221abf9",
      "new_mode": 33188,
      "new_path": "compiler/src/iree/compiler/GlobalOptimization/test/detach_elementwise_from_named_ops.mlir"
    }
  ]
}
