)]}'
{
  "commit": "dd9207e6486a74816f858c129207a0d8a3896ec7",
  "tree": "6ab4b3e7f02b34c2a094c951d606590cb2c912f5",
  "parents": [
    "d6a4edd480a8a06d3b32f5be8c4b3dd70332dd24"
  ],
  "author": {
    "name": "Bill Wendling",
    "email": "isanbard@gmail.com",
    "time": "Tue Oct 06 06:14:26 2026 -0700"
  },
  "committer": {
    "name": "Bill Wendling",
    "email": "isanbard@gmail.com",
    "time": "Thu Oct 08 00:32:07 2026 -0700"
  },
  "message": "[RegAllocFast] Fold foldable inline asm operands under register pressure\n\nAn inline asm register operand marked foldable (from an \"rm\" constraint)\nmay be replaced with a stack slot when the register allocator runs out\nof registers. The greedy allocator does that when it spills the value.\nThe fast allocator can\u0027t: it assigns the operands of an instruction one\nat a time, and folding replaces the instruction. So it reported\n\"inline assembly requires more registers than available\" instead.\n\nBefore allocating a block, estimate from each inline asm\u0027s own operands\nwhether they fit in registers, and fold as many foldable registers as\nneeded to make them fit, so the common case without pressure still gets\na register. Values that only live across the asm don\u0027t count, since the\nallocator spills them when it needs their registers. The estimate\nfollows allocateInstruction():\n\n- First all defs get distinct registers, avoiding physreg defs; then all\n  uses, along with the defs still occupied while the uses are read\n  (early-clobber and tied defs, see isLiveThroughDef()), get distinct\n  registers, avoiding physreg uses and early-clobber physreg defs.\n- A register counts against another register class as many times as one\n  of its registers overlaps that class\u0027s registers, so e.g. 32-bit \"rm\"\n  operands compete with 64-bit operands for the same registers.\n- A value used by both an \"rm\" and an \"r\" operand isn\u0027t folded, since\n  that frees no register.\n- An input tied to a def keeps a register of its own when the allocator\n  lowers the tie itself and the input is read later in the block. Kill\n  flags are optional, so a missing one doesn\u0027t mean the input lives on.\n\nFolding a register folds all of its operands at once, with one store\nbefore the asm and one reload after it. It uses the register\u0027s own spill\nslot, so that a block that reloads the register, such as an\nINLINEASM_BR\u0027s indirect target, which the reload after the asm doesn\u0027t\nreach, finds the value the asm wrote.\n\nThe whole thing is skipped for functions without inline asm.\n\nNothing in tree marks an inline asm register operand foldable yet, so\nthe tests set the \"foldable\" flag in MIR.\n\nThis follows the shape of the unmerged #74344, \"[RegAllocFast] fold\nfoldable inline asm\", with a pressure estimate instead of folding\nunconditionally, per the review there.\n\nAssisted-by: Claude Opus 5.5\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "76237fa260d37fa22faad33cd83c670772195580",
      "old_mode": 33188,
      "old_path": "llvm/lib/CodeGen/RegAllocFast.cpp",
      "new_id": "cf9c3d594d0d6027ea593522484058e18a8ece4f",
      "new_mode": 33188,
      "new_path": "llvm/lib/CodeGen/RegAllocFast.cpp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "87f7239f56bdb26b97dd8a1ed8616aecd6dac6d0",
      "new_mode": 33188,
      "new_path": "llvm/test/CodeGen/X86/regallocfast-inline-asm-fold-pressure.mir"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "870277e0fe2f19e4abcf6128d6577c77993faa1d",
      "new_mode": 33188,
      "new_path": "llvm/test/CodeGen/X86/regallocfast-inline-asm-fold.mir"
    }
  ]
}
