)]}'
{
  "commit": "398d9979ec07ac3f478d6e2d941609cd4eeccf12",
  "tree": "6bfc1edf800899a9261625a615880d3dfe5e34e8",
  "parents": [
    "39de311c74d13949feab1fc9fe45654e0219b065"
  ],
  "author": {
    "name": "Roger Sayle",
    "email": "roger@nextmovesoftware.com",
    "time": "Mon Jun 15 20:09:55 2026 +0100"
  },
  "committer": {
    "name": "Roger Sayle",
    "email": "roger@nextmovesoftware.com",
    "time": "Mon Jun 15 20:12:31 2026 +0100"
  },
  "message": "i386: Tweak cost of SSE fabs/fneg in ix86_insn_cost.\n\nThis patch fixes a poor interaction between the splitters for SSE\nfloating point abs/neg in the i386 backend, and the late-combine pass.\nBefore reload, these patterns exist as a PARALLEL containing the USE\nof a value (pseudo) holding the sign-bit.  Currently late-combine\npropagates this sign-bit mask from the constant pool, changing the\nUSE of a REG to the USE of a MEM.  This unCSE is reasonable if this\nMEM is used only once, but less than optimal if this MEM is accessed\nmany times.\n\nThe problem is that this USE doesn\u0027t currently have a cost in\nix86_insn_cost, so propagating this load from memory into the USE\nmakes if free (to combine\u0027s profitable replacement calculation).\nThis patch improve things by providing a nominal cost for USEs of\nMEM.\n\nAs an example, consider the following function:\n\nfloat x, y, z;\nvoid foo()\n{\n  x \u003d -x;\n  y \u003d -y;\n  z \u003d -z;\n}\n\nCurrently with -O2 GCC generates three loads from the constant pool:\n\n        movss   x(%rip), %xmm0\n        xorps   .LC0(%rip), %xmm0\n        movss   %xmm0, x(%rip)\n        movss   y(%rip), %xmm0\n        xorps   .LC0(%rip), %xmm0\n        movss   %xmm0, y(%rip)\n        movss   z(%rip), %xmm0\n        xorps   .LC0(%rip), %xmm0\n        movss   %xmm0, z(%rip)\n        ret\n\nWith the patch below, this load remains CSEd.\n\n        movss   x(%rip), %xmm0\n        movss   .LC0(%rip), %xmm1\n        xorps   %xmm1, %xmm0\n        movss   %xmm0, x(%rip)\n        movss   y(%rip), %xmm0\n        xorps   %xmm1, %xmm0\n        movss   %xmm0, y(%rip)\n        movss   z(%rip), %xmm0\n        xorps   %xmm1, %xmm0\n        movss   %xmm0, z(%rip)\n        ret\n\nNote this is one more instruction, but code size is smaller and\nthe total cost (as calculated by the i386 backend) is lower.\nFor a single neg/abs the memory address is still propagated.\n\n2026-06-15  Roger Sayle  \u003croger@nextmovesoftware.com\u003e\n\ngcc/ChangeLog\n\t* config/i386/i386.cc (ix86_insn_cost): Add a suitable penalty\n\tfor USE of a MEM in a PARALLEL (for *\u003cabsneg\u003e[sd]f2_1 splitter).\n\ngcc/testsuite/ChangeLog\n\t* gcc.target/i386/fabsneg-2.c: New test case.\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "2945081234b3c5c073684aacf69f4a173822d571",
      "old_mode": 33188,
      "old_path": "gcc/config/i386/i386.cc",
      "new_id": "b1fd86c2b320e3ce191fb4dd314a4f97782664f4",
      "new_mode": 33188,
      "new_path": "gcc/config/i386/i386.cc"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "dd40c755a49bbf3577ce074e6dd02432848e4a38",
      "new_mode": 33188,
      "new_path": "gcc/testsuite/gcc.target/i386/fabsneg-2.c"
    }
  ]
}
