get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.1/patches/2232038/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2232038,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2232038/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260502101755.308183-1-disservin.social@gmail.com/",
    "project": {
        "id": 17,
        "url": "http://patchwork.ozlabs.org/api/1.1/projects/17/?format=api",
        "name": "GNU Compiler Collection",
        "link_name": "gcc",
        "list_id": "gcc-patches.gcc.gnu.org",
        "list_email": "gcc-patches@gcc.gnu.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null
    },
    "msgid": "<20260502101755.308183-1-disservin.social@gmail.com>",
    "date": "2026-05-02T10:17:56",
    "name": "Add __builtin_bitreverse{8,16,32,64} [PR50481]",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "2b9568657abec49fec1910cefaa9f76f3a52f671",
    "submitter": {
        "id": 93304,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/93304/?format=api",
        "name": "Disservin",
        "email": "disservin.social@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20260502101755.308183-1-disservin.social@gmail.com/mbox/",
    "series": [
        {
            "id": 502525,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/502525/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=502525",
            "date": "2026-05-02T10:17:56",
            "name": "Add __builtin_bitreverse{8,16,32,64} [PR50481]",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/502525/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2232038/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2232038/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=PaV1kpZ0;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)",
            "sourceware.org;\n\tdkim=pass (2048-bit key,\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=PaV1kpZ0",
            "sourceware.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com",
            "sourceware.org; spf=pass smtp.mailfrom=gmail.com",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=2a00:1450:4864:20::32f"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g73nH3cpbz1yGq\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 02 May 2026 20:20:02 +1000 (AEST)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 047104A9A8B5\n\tfor <incoming@patchwork.ozlabs.org>; Sat,  2 May 2026 10:20:00 +0000 (GMT)",
            "from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com\n [IPv6:2a00:1450:4864:20::32f])\n by sourceware.org (Postfix) with ESMTPS id 15F654A99307\n for <gcc-patches@gcc.gnu.org>; Sat,  2 May 2026 10:19:31 +0000 (GMT)",
            "by mail-wm1-x32f.google.com with SMTP id\n 5b1f17b1804b1-4891e5b9c1fso22667565e9.2\n for <gcc-patches@gcc.gnu.org>; Sat, 02 May 2026 03:19:31 -0700 (PDT)",
            "from ABC.fritz.box ([95.88.170.219])\n by smtp.gmail.com with ESMTPSA id\n 5b1f17b1804b1-48a8ebc4201sm192159625e9.15.2026.05.02.03.19.28\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Sat, 02 May 2026 03:19:28 -0700 (PDT)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org 047104A9A8B5",
            "OpenDKIM Filter v2.11.0 sourceware.org 15F654A99307"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 15F654A99307",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 15F654A99307",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777717171; cv=none;\n b=sri9lFFLmE0BrS0DgQLeRvdgkvlI333FXdQpVEXLK0cqacTsAv7yIkzFysPzVKAOBOBPuAM/GD5mOP+a3I7mqFWqhG3dPat7A2YM8PxVzztblZrA+bjyTJH862xmFVRjoMFnMshpsJWc+qSvtHBOpJyeOTKAnohLMS/tLyoWqbM=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1777717171; c=relaxed/simple;\n bh=MwMOH9ad5UxgjWC6+4orafbJcN2NMgZnvF/utoYL8Ak=;\n h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version;\n b=ESxiN0uFfFnFiDkCDEKam4IKJsWNDVSsePrTpVt2HyTb0CsxGV687JUdHbxdZbgJwBGiNrXfjDoMd1YilE21Vg/YXTad/qLlzODynDyWAUxw4Uj5bbec96z6TsLkm4DQ44LIYeJ5HZW1QameRns1WG+dekgbIPi31JentWg8fvs=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1777717169; x=1778321969; darn=gcc.gnu.org;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:from:to:cc:subject:date:message-id:reply-to;\n bh=ECu863mLevfG7k9yt4ujQuNtFirdrG7sZZYXbqCtZt4=;\n b=PaV1kpZ0b1drR++DfV4WziW98S+fMeU8vo4LB+HWiVsBA2YD/cVPtM/HRXjvWDmvme\n k4Oqs5E67b1lE2xEUhRv3zEh+4qeZzAMuWAwM4RMN9iyKN38h2OuK0YzKhrG2DAS42Ec\n gis4YrLv93Ugqq3e31CH9iUz5+6AMO7TLwow5FkcnFT77uU4VIimwPMlzrFGd31+L7vY\n oChEwEwIBmDKsDmmVu+2xz4zwE9b/r29z4JMjQrYS3Tch62X+oEc6ITdFbURdo5V+xv0\n 6pNWUCH96HogRmoxgIeuNkOJeItgX8S9sgYBqTqCZPrO9dYdKDEnFpxlPQHTQbqF4YLB\n yzvQ==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777717169; x=1778321969;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=ECu863mLevfG7k9yt4ujQuNtFirdrG7sZZYXbqCtZt4=;\n b=ObZrJnhqtL0n/J15KpTB/2huVlP/inIvwEHTO7lfW+b3jqUUztcRfQfhsJQQo9D+BH\n 5RcIuxOdQhmpSeQX1KS0Q7kAOAcSj7CJqNqmaPTVKQQkrNolgjtTEJQEA+xehjCpYNpt\n fRM5NpyZGmCcvkw1n4IWUHLEZxEadaf9SGKuaxdHPYehB664/KIkfsqYKmrv096Pak/x\n TAlYkM2tRsQFn+vrgiZ10bktvHdRYuHd670lRE63bZEBP4ntiOIa2az7irKI4g74nxil\n 6fxHVYGmDX9vN5ykMnVjgG4LUpozTD2QhlQF2vb4TqC1ZJagVTiQudkNd5FZiPim/5qu\n vK/g==",
        "X-Gm-Message-State": "AOJu0YzSBAaJed3PfNsJB7nsuPsPuHvz5eBsgo1YUqvkXASqIGPPh19U\n cE1ZNn5UhDd3VYjWLaHiWYeih+dp7oFBBuy5VZaaJElL3if99YsNtTWuzcAaTA==",
        "X-Gm-Gg": "AeBDietzmrdSktsSwdHQPZzEPiIVK7gl/xYt6Wu6tvXwy5jFZCSB+ELJOnjZLgHAhCk\n NuqL3aIze/DY1PVG3lzmacylimzXauztLP/FLBxRi1iTmf5w8YDf1p/S3lT9pL1WUGa/iS3+cko\n dlaR7YXAC/N92SI2jpzUlh41UcPcoDC7/V6YCW80sQ4wWMT3AkeadhE2If1R2pUQsSrWun1uvLa\n 3dX7OFfeDnUw52ZufUEWryvUvpntK40TDtKyw+1v6k2x5Ctwv0J6om4lfZ9VzplmTGbABxX7Qja\n PTyiIK0Gu7njeiUMeCwjKdwWcHX/b1xAatuQvWS1Ksbrj11CyQr6JcnPDvQS0lOaZ03T/K7nmB6\n 6aXpkRKLm5X7+mi7wXnohnIBuBmnbhNpBq9qIEfFTgMOdIWbc+qilTv18qrz5VP8utNWwrZ4PCY\n hKOERi2G7IFaN6S5yJqlDizFpJCr30/aQGDukxcSAtxVE=",
        "X-Received": "by 2002:a05:600c:444c:b0:488:a824:fe04 with SMTP id\n 5b1f17b1804b1-48a98671f6fmr36185375e9.26.1777717169344;\n Sat, 02 May 2026 03:19:29 -0700 (PDT)",
        "From": "Disservin <disservin.social@gmail.com>",
        "To": "gcc-patches@gcc.gnu.org",
        "Cc": "Disservin <disservin.social@gmail.com>",
        "Subject": "[PATCH] Add __builtin_bitreverse{8,16,32,64} [PR50481]",
        "Date": "Sat,  2 May 2026 12:17:56 +0200",
        "Message-Id": "<20260502101755.308183-1-disservin.social@gmail.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "gcc-patches@gcc.gnu.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>",
        "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>",
        "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>",
        "List-Post": "<mailto:gcc-patches@gcc.gnu.org>",
        "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>",
        "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>",
        "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"
    },
    "content": "This patch adds a first version of __builtin_bitreverse{8,16,32,64} builtins.\nPR target/50481\nhttps://gcc.gnu.org/bugzilla/show_bug.cgi?id=50481\n\nFuture work could optimize this on specific targets:\n  - ARM: lower to RBIT\n  - x86 with GFNI: lower to vgf2p8affineqb [1]\n\nThis is my first GCC patch; any feedback on process or style is welcome.\n\n[1] https://wunkolo.github.io/post/2020/11/gf2p8affineqb-bit-reversal/\n---\n gcc/builtin-types.def                         |   1 +\n gcc/builtins.cc                               |  14 ++\n gcc/builtins.def                              |   4 +\n gcc/doc/extend.texi                           |  19 +++\n gcc/fold-const-call.cc                        |   8 ++\n gcc/fold-const.cc                             |   4 +\n gcc/optabs.cc                                 | 133 ++++++++++++++++++\n gcc/optabs.def                                |   1 +\n .../gcc.dg/builtin-bitreverse-fold.c          |   9 ++\n gcc/testsuite/gcc.dg/builtin-bitreverse64.c   |  24 ++++\n gcc/tree-ssa-ccp.cc                           |   4 +\n gcc/tree-ssa-phiopt.cc                        |   8 ++\n 12 files changed, 229 insertions(+)\n create mode 100644 gcc/testsuite/gcc.dg/builtin-bitreverse-fold.c\n create mode 100644 gcc/testsuite/gcc.dg/builtin-bitreverse64.c",
    "diff": "diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def\nindex ab0cbc65c..365badca2 100644\n--- a/gcc/builtin-types.def\n+++ b/gcc/builtin-types.def\n@@ -412,6 +412,7 @@ DEF_FUNCTION_TYPE_1 (BT_FN_INT16_FLOAT, BT_INT16, BT_FLOAT)\n DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_FLOAT, BT_UINT32, BT_FLOAT)\n DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_FLOAT, BT_UINT16, BT_FLOAT)\n DEF_FUNCTION_TYPE_1 (BT_FN_UINT8_FLOAT, BT_UINT8, BT_FLOAT)\n+DEF_FUNCTION_TYPE_1 (BT_FN_UINT8_UINT8, BT_UINT8, BT_UINT8)\n DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_UINT16, BT_UINT16, BT_UINT16)\n DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_UINT32, BT_UINT32, BT_UINT32)\n DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_UINT64, BT_UINT64, BT_UINT64)\ndiff --git a/gcc/builtins.cc b/gcc/builtins.cc\nindex 692e20088..0475bb88a 100644\n--- a/gcc/builtins.cc\n+++ b/gcc/builtins.cc\n@@ -8184,6 +8184,16 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,\n \treturn target;\n       break;\n \n+    case BUILT_IN_BITREVERSE8:\n+    case BUILT_IN_BITREVERSE16:\n+    case BUILT_IN_BITREVERSE32:\n+    case BUILT_IN_BITREVERSE64:\n+      target = expand_builtin_unop (target_mode, exp, target, subtarget,\n+\t\t\t\t    bitreverse_optab);\n+      if (target)\n+\treturn target;\n+      break;\n+\n     CASE_INT_FN (BUILT_IN_FFS):\n       target = expand_builtin_unop (target_mode, exp, target,\n \t\t\t\t    subtarget, ffs_optab);\n@@ -12343,6 +12353,10 @@ is_inexpensive_builtin (tree decl)\n       case BUILT_IN_BSWAP32:\n       case BUILT_IN_BSWAP64:\n       case BUILT_IN_BSWAP128:\n+      case BUILT_IN_BITREVERSE8:\n+      case BUILT_IN_BITREVERSE16:\n+      case BUILT_IN_BITREVERSE32:\n+      case BUILT_IN_BITREVERSE64:\n       case BUILT_IN_CLZ:\n       case BUILT_IN_CLZIMAX:\n       case BUILT_IN_CLZL:\ndiff --git a/gcc/builtins.def b/gcc/builtins.def\nindex 8ab0599b1..68838de55 100644\n--- a/gcc/builtins.def\n+++ b/gcc/builtins.def\n@@ -1024,6 +1024,10 @@ DEF_GCC_BUILTIN        (BUILT_IN_BSWAP16, \"bswap16\", BT_FN_UINT16_UINT16, ATTR_C\n DEF_GCC_BUILTIN        (BUILT_IN_BSWAP32, \"bswap32\", BT_FN_UINT32_UINT32, ATTR_CONST_NOTHROW_LEAF_LIST)\n DEF_GCC_BUILTIN        (BUILT_IN_BSWAP64, \"bswap64\", BT_FN_UINT64_UINT64, ATTR_CONST_NOTHROW_LEAF_LIST)\n DEF_GCC_BUILTIN        (BUILT_IN_BSWAP128, \"bswap128\", BT_FN_UINT128_UINT128, ATTR_CONST_NOTHROW_LEAF_LIST)\n+DEF_GCC_BUILTIN        (BUILT_IN_BITREVERSE8, \"bitreverse8\", BT_FN_UINT8_UINT8, ATTR_CONST_NOTHROW_LEAF_LIST)\n+DEF_GCC_BUILTIN        (BUILT_IN_BITREVERSE16, \"bitreverse16\", BT_FN_UINT16_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST)\n+DEF_GCC_BUILTIN        (BUILT_IN_BITREVERSE32, \"bitreverse32\", BT_FN_UINT32_UINT32, ATTR_CONST_NOTHROW_LEAF_LIST)\n+DEF_GCC_BUILTIN        (BUILT_IN_BITREVERSE64, \"bitreverse64\", BT_FN_UINT64_UINT64, ATTR_CONST_NOTHROW_LEAF_LIST)\n \n DEF_EXT_LIB_BUILTIN    (BUILT_IN_CLEAR_CACHE, \"__clear_cache\", BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LEAF_LIST)\n /* [trans-mem]: Adjust BUILT_IN_TM_CALLOC if BUILT_IN_CALLOC is changed.  */\ndiff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi\nindex 0faa5323c..aa1f526f7 100644\n--- a/gcc/doc/extend.texi\n+++ b/gcc/doc/extend.texi\n@@ -16064,6 +16064,25 @@ Similar to @code{__builtin_bswap64}, except the argument and return types\n are 128-bit.  Only supported on targets when 128-bit types are supported.\n @enddefbuiltin\n \n+@defbuiltin{uint8_t __builtin_bitreverse8 (uint8_t @var{x})}\n+Returns @var{x} with all bits reversed.\n+@enddefbuiltin\n+\n+@defbuiltin{uint16_t __builtin_bitreverse16 (uint16_t @var{x})}\n+Similar to @code{__builtin_bitreverse8}, except the argument and return types\n+are 16-bit.\n+@enddefbuiltin\n+\n+@defbuiltin{uint32_t __builtin_bitreverse32 (uint32_t @var{x})}\n+Similar to @code{__builtin_bitreverse8}, except the argument and return types\n+are 32-bit.\n+@enddefbuiltin\n+\n+@defbuiltin{uint64_t __builtin_bitreverse64 (uint64_t @var{x})}\n+Similar to @code{__builtin_bitreverse8}, except the argument and return types\n+are 64-bit.\n+@enddefbuiltin\n+\n @node CRC Builtins\n @subsection CRC Builtins\n @cindex CRC builtins\ndiff --git a/gcc/fold-const-call.cc b/gcc/fold-const-call.cc\nindex 7dd1b21c3..7e8299513 100644\n--- a/gcc/fold-const-call.cc\n+++ b/gcc/fold-const-call.cc\n@@ -1102,6 +1102,14 @@ fold_const_call_ss (wide_int *result, combined_fn fn, const wide_int_ref &arg,\n \t\t\t\t\t   TYPE_SIGN (arg_type)));\n       return true;\n \n+    case CFN_BUILT_IN_BITREVERSE8:\n+    case CFN_BUILT_IN_BITREVERSE16:\n+    case CFN_BUILT_IN_BITREVERSE32:\n+    case CFN_BUILT_IN_BITREVERSE64:\n+      *result = wi::bitreverse (wide_int::from (arg, precision,\n+\t\t\t\t\t\t TYPE_SIGN (arg_type)));\n+      return true;\n+\n     default:\n       return false;\n     }\ndiff --git a/gcc/fold-const.cc b/gcc/fold-const.cc\nindex 56503e570..3bc82a108 100644\n--- a/gcc/fold-const.cc\n+++ b/gcc/fold-const.cc\n@@ -14984,6 +14984,10 @@ tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1,\n     case CFN_BUILT_IN_BSWAP32:\n     case CFN_BUILT_IN_BSWAP64:\n     case CFN_BUILT_IN_BSWAP128:\n+    case CFN_BUILT_IN_BITREVERSE8:\n+    case CFN_BUILT_IN_BITREVERSE16:\n+    case CFN_BUILT_IN_BITREVERSE32:\n+    case CFN_BUILT_IN_BITREVERSE64:\n       /* Always true.  */\n       return true;\n \ndiff --git a/gcc/optabs.cc b/gcc/optabs.cc\nindex 111b9be99..bf9ce8ee7 100644\n--- a/gcc/optabs.cc\n+++ b/gcc/optabs.cc\n@@ -2941,6 +2941,129 @@ expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)\n   return target;\n }\n \n+/* Try calculating (bitreverse x) using masks and shifts.  */\n+\n+static rtx\n+expand_bitreverse (scalar_int_mode mode, rtx op0, rtx target)\n+{\n+  unsigned int precision = GET_MODE_BITSIZE (mode);\n+  rtx_insn *last;\n+\n+  /* Operation requires at least 4 bits (one nibble swap makes no sense below that) */\n+  if (precision < 4)\n+    return NULL_RTX;\n+\n+  if (target == 0\n+      || target == op0\n+      || reg_overlap_mentioned_p (target, op0))\n+    target = gen_reg_rtx (mode);\n+\n+  last = get_last_insn ();\n+\n+  rtx x, lo, hi;\n+\n+  /* Step 1: byte-swap (only meaningful for >= 16 bits) */\n+  if (precision >= 16)\n+    {\n+      x = expand_unop (mode, bswap_optab, op0, NULL_RTX, true);\n+      if (x == NULL_RTX)\n+        goto fail;\n+    }\n+  else\n+    x = op0;\n+\n+  /* Step 2: swap nibbles within each byte (shift=4, only for >= 8 bits) */\n+  if (precision >= 8)\n+    {\n+      wide_int mask = wi::zero (precision);\n+      for (unsigned int start = 0; start < precision; start += 8)\n+        mask = wi::bit_or (mask, wi::shifted_mask (start, 4, false, precision));\n+\n+      rtx mask_rtx     = immed_wide_int_const (mask, mode);\n+\n+      hi = expand_simple_binop (mode, LSHIFTRT, x, GEN_INT (4),\n+                                NULL_RTX, true, OPTAB_LIB_WIDEN);\n+      if (hi == NULL_RTX) goto fail;\n+      hi = expand_binop (mode, and_optab, hi, mask_rtx,\n+                         NULL_RTX, true, OPTAB_LIB_WIDEN);\n+      if (hi == NULL_RTX) goto fail;\n+\n+      lo = expand_binop (mode, and_optab, x, mask_rtx,\n+                         NULL_RTX, true, OPTAB_LIB_WIDEN);\n+      if (lo == NULL_RTX) goto fail;\n+      lo = expand_simple_binop (mode, ASHIFT, lo, GEN_INT (4),\n+                                NULL_RTX, true, OPTAB_LIB_WIDEN);\n+      if (lo == NULL_RTX) goto fail;\n+\n+      x = expand_binop (mode, ior_optab, hi, lo,\n+                        NULL_RTX, true, OPTAB_LIB_WIDEN);\n+      if (x == NULL_RTX) goto fail;\n+    }\n+\n+  /* Step 3: swap pairs of bits within each nibble (shift=2) */\n+  {\n+    wide_int mask = wi::zero (precision);\n+    for (unsigned int start = 0; start < precision; start += 4)\n+      mask = wi::bit_or (mask, wi::shifted_mask (start, 2, false, precision));\n+\n+    rtx mask_rtx     = immed_wide_int_const (mask, mode);\n+\n+    hi = expand_simple_binop (mode, LSHIFTRT, x, GEN_INT (2),\n+                              NULL_RTX, true, OPTAB_LIB_WIDEN);\n+    if (hi == NULL_RTX) goto fail;\n+    hi = expand_binop (mode, and_optab, hi, mask_rtx,\n+                       NULL_RTX, true, OPTAB_LIB_WIDEN);\n+    if (hi == NULL_RTX) goto fail;\n+\n+    lo = expand_binop (mode, and_optab, x, mask_rtx,\n+                       NULL_RTX, true, OPTAB_LIB_WIDEN);\n+    if (lo == NULL_RTX) goto fail;\n+    lo = expand_simple_binop (mode, ASHIFT, lo, GEN_INT (2),\n+                              NULL_RTX, true, OPTAB_LIB_WIDEN);\n+    if (lo == NULL_RTX) goto fail;\n+\n+    x = expand_binop (mode, ior_optab, hi, lo,\n+                      NULL_RTX, true, OPTAB_LIB_WIDEN);\n+    if (x == NULL_RTX) goto fail;\n+  }\n+\n+  /* Step 4: swap adjacent bits (shift=1) */\n+  {\n+    wide_int mask = wi::zero (precision);\n+    for (unsigned int start = 0; start < precision; start += 2)\n+      mask = wi::bit_or (mask, wi::shifted_mask (start, 1, false, precision));\n+\n+    rtx mask_rtx     = immed_wide_int_const (mask, mode);\n+\n+    hi = expand_simple_binop (mode, LSHIFTRT, x, GEN_INT (1),\n+                              NULL_RTX, true, OPTAB_LIB_WIDEN);\n+    if (hi == NULL_RTX) goto fail;\n+    hi = expand_binop (mode, and_optab, hi, mask_rtx,\n+                       NULL_RTX, true, OPTAB_LIB_WIDEN);\n+    if (hi == NULL_RTX) goto fail;\n+\n+    lo = expand_binop (mode, and_optab, x, mask_rtx,\n+                       NULL_RTX, true, OPTAB_LIB_WIDEN);\n+    if (lo == NULL_RTX) goto fail;\n+    lo = expand_simple_binop (mode, ASHIFT, lo, GEN_INT (1),\n+                              NULL_RTX, true, OPTAB_LIB_WIDEN);\n+    if (lo == NULL_RTX) goto fail;\n+\n+    x = expand_binop (mode, ior_optab, hi, lo,\n+                      target, true, OPTAB_LIB_WIDEN);\n+    if (x == NULL_RTX) goto fail;\n+  }\n+\n+  if (x != target)\n+    emit_move_insn (target, x);\n+\n+  return target;\n+\n+ fail:\n+  delete_insns_since (last);\n+  return NULL_RTX;\n+}\n+\n /* Try calculating (parity x) as (and (popcount x) 1), where\n    popcount can also be done in a wider mode.  */\n static rtx\n@@ -3391,6 +3514,16 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,\n       goto try_libcall;\n     }\n \n+  if (unoptab == bitreverse_optab)\n+    {\n+      if (is_a <scalar_int_mode> (mode, &int_mode))\n+\t{\n+\t  temp = expand_bitreverse (int_mode, op0, target);\n+\t  if (temp)\n+\t    return temp;\n+\t}\n+    }\n+\n   /* Neg should be tried via expand_absneg_bit before widening.  */\n   if (optab_to_code (unoptab) == NEG)\n     {\ndiff --git a/gcc/optabs.def b/gcc/optabs.def\nindex 193f42a72..7ccea1854 100644\n--- a/gcc/optabs.def\n+++ b/gcc/optabs.def\n@@ -184,6 +184,7 @@ OPTAB_VC(absv_optab, \"absv$I$a2\", ABS)\n OPTAB_VX(absv_optab, \"abs$F$a2\")\n OPTAB_NL(one_cmpl_optab, \"one_cmpl$a2\", NOT, \"one_cmpl\", '2', gen_int_libfunc)\n OPTAB_NC(bswap_optab, \"bswap$a2\", BSWAP)\n+OPTAB_NC(bitreverse_optab, \"bitreverse$a2\", BITREVERSE)\n OPTAB_NL(ffs_optab, \"ffs$a2\", FFS, \"ffs\", '2', gen_int_libfunc)\n OPTAB_NL(clz_optab, \"clz$a2\", CLZ, \"clz\", '2', gen_int_libfunc)\n OPTAB_NL(ctz_optab, \"ctz$a2\", CTZ, \"ctz\", '2', gen_int_libfunc)\ndiff --git a/gcc/testsuite/gcc.dg/builtin-bitreverse-fold.c b/gcc/testsuite/gcc.dg/builtin-bitreverse-fold.c\nnew file mode 100644\nindex 000000000..4a8cfb3f1\n--- /dev/null\n+++ b/gcc/testsuite/gcc.dg/builtin-bitreverse-fold.c\n@@ -0,0 +1,9 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-std=gnu11\" } */\n+\n+_Static_assert (__builtin_bitreverse8 (0x01u) == 0x80u, \"bitreverse8\");\n+_Static_assert (__builtin_bitreverse16 (0x0001u) == 0x8000u, \"bitreverse16\");\n+_Static_assert (__builtin_bitreverse32 (0x12345678u) == 0x1e6a2c48u,\n+\t\t\"bitreverse32\");\n+_Static_assert (__builtin_bitreverse64 (0x0123456789abcdefull)\n+\t\t == 0xf7b3d591e6a2c480ull, \"bitreverse64\");\ndiff --git a/gcc/testsuite/gcc.dg/builtin-bitreverse64.c b/gcc/testsuite/gcc.dg/builtin-bitreverse64.c\nnew file mode 100644\nindex 000000000..8419452ff\n--- /dev/null\n+++ b/gcc/testsuite/gcc.dg/builtin-bitreverse64.c\n@@ -0,0 +1,24 @@\n+/* { dg-do run } */\n+/* { dg-options \"-O2\" } */\n+\n+extern void abort (void);\n+\n+static unsigned long long\n+br64 (unsigned long long x)\n+{\n+  return __builtin_bitreverse64 (x);\n+}\n+\n+int\n+main (void)\n+{\n+  if (br64 (0x0000000000000000ull) != 0x0000000000000000ull)\n+    abort ();\n+  if (br64 (0x0000000000000001ull) != 0x8000000000000000ull)\n+    abort ();\n+  if (br64 (0x0123456789abcdefull) != 0xf7b3d591e6a2c480ull)\n+    abort ();\n+  if (br64 (0xffffffffffffffffull) != 0xffffffffffffffffull)\n+    abort ();\n+  return 0;\n+}\ndiff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc\nindex 952ebf17e..974bef178 100644\n--- a/gcc/tree-ssa-ccp.cc\n+++ b/gcc/tree-ssa-ccp.cc\n@@ -2435,6 +2435,10 @@ evaluate_stmt (gimple *stmt)\n \t    case BUILT_IN_BSWAP32:\n \t    case BUILT_IN_BSWAP64:\n \t    case BUILT_IN_BSWAP128:\n+\t    case BUILT_IN_BITREVERSE8:\n+\t    case BUILT_IN_BITREVERSE16:\n+\t    case BUILT_IN_BITREVERSE32:\n+\t    case BUILT_IN_BITREVERSE64:\n \t      val = get_value_for_expr (gimple_call_arg (stmt, 0), true);\n \t      if (val.lattice_val == UNDEFINED)\n \t\tbreak;\ndiff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc\nindex 0bf7e58b8..50ddeaa67 100644\n--- a/gcc/tree-ssa-phiopt.cc\n+++ b/gcc/tree-ssa-phiopt.cc\n@@ -819,6 +819,10 @@ empty_bb_or_one_feeding_into_p (basic_block bb,\n \tcase CFN_BUILT_IN_BSWAP32:\n \tcase CFN_BUILT_IN_BSWAP64:\n \tcase CFN_BUILT_IN_BSWAP128:\n+\tcase CFN_BUILT_IN_BITREVERSE8:\n+\tcase CFN_BUILT_IN_BITREVERSE16:\n+\tcase CFN_BUILT_IN_BITREVERSE32:\n+\tcase CFN_BUILT_IN_BITREVERSE64:\n \tCASE_CFN_FFS:\n \tCASE_CFN_PARITY:\n \tCASE_CFN_POPCOUNT:\n@@ -2578,6 +2582,10 @@ cond_removal_in_builtin_zero_pattern (basic_block cond_bb,\n     case CFN_BUILT_IN_BSWAP32:\n     case CFN_BUILT_IN_BSWAP64:\n     case CFN_BUILT_IN_BSWAP128:\n+    case CFN_BUILT_IN_BITREVERSE8:\n+    case CFN_BUILT_IN_BITREVERSE16:\n+    case CFN_BUILT_IN_BITREVERSE32:\n+    case CFN_BUILT_IN_BITREVERSE64:\n     CASE_CFN_FFS:\n     CASE_CFN_PARITY:\n     CASE_CFN_POPCOUNT:\n",
    "prefixes": []
}