Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2232490/?format=api
{ "id": 2232490, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2232490/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260504152323.4034277-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": "<20260504152323.4034277-1-disservin.social@gmail.com>", "date": "2026-05-04T15:23:24", "name": "[v2] Add __builtin_bitreverse{8,16,32,64} [PR50481]", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "1765c69facaa99d4673ce3dcf418dd60cc4517ec", "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/20260504152323.4034277-1-disservin.social@gmail.com/mbox/", "series": [ { "id": 502683, "url": "http://patchwork.ozlabs.org/api/1.1/series/502683/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=502683", "date": "2026-05-04T15:23:24", "name": "[v2] Add __builtin_bitreverse{8,16,32,64} [PR50481]", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/502683/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2232490/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2232490/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=GbU5MmhD;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.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=GbU5MmhD", "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::32d" ], "Received": [ "from vm01.sourceware.org (vm01.sourceware.org [38.145.34.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 4g8QSZ6xyrz1yKC\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 05 May 2026 01:25:17 +1000 (AEST)", "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id A67494BA23F3\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 4 May 2026 15:25:15 +0000 (GMT)", "from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com\n [IPv6:2a00:1450:4864:20::32d])\n by sourceware.org (Postfix) with ESMTPS id 7F73C4BA23F3\n for <gcc-patches@gcc.gnu.org>; Mon, 4 May 2026 15:24:46 +0000 (GMT)", "by mail-wm1-x32d.google.com with SMTP id\n 5b1f17b1804b1-488ab2db91aso51300465e9.3\n for <gcc-patches@gcc.gnu.org>; Mon, 04 May 2026 08:24:46 -0700 (PDT)", "from ABC.fritz.box ([95.88.170.219])\n by smtp.gmail.com with ESMTPSA id\n 5b1f17b1804b1-48a8ebb2f32sm283635285e9.13.2026.05.04.08.24.43\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Mon, 04 May 2026 08:24:44 -0700 (PDT)" ], "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 sourceware.org A67494BA23F3", "OpenDKIM Filter v2.11.0 sourceware.org 7F73C4BA23F3" ], "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 7F73C4BA23F3", "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 7F73C4BA23F3", "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777908286; cv=none;\n b=OpERPqOtcJar6WtZHjp6tSDeX4zrqpi8yXjpD6rFJU7lOSt5tv7y4X5DXGF9YwRuhLNzVFCg3A7HZtL9R1Kd3fPRbr0nkNZpWonypbhM7GF0CHJiH9NNt4sjSnZ0A4MINzRgpGiIW5ofRgHXZrpub1XMIT9U/SFRTBp7bkcNJR4=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1777908286; c=relaxed/simple;\n bh=dTMSdCjCr5EojSuDTeziqNNaoDNod6eYZ7NWA8BPzN4=;\n h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version;\n b=PFozCf/e7i4fjV6e7IR5A8DtOpuZQgunk9ibo/pUfK/CyEJ+EOO7Ld0Mr4n7l5NC9giL3+B8mebqZPvNU6IaoT2sbs7hf9QK6i8qslw8kuQ+gyQrKcyg2BS+sZ2kzF/66uUoHSOsvCWQ4X+uWcDOap++/UkH0W6GUVyrjh1GOCE=", "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=1777908285; x=1778513085; darn=gcc.gnu.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=e5SrUHjOSHTBq0/mFBnBMs/u2s9oJydgiRS1iqSgBsU=;\n b=GbU5MmhDtNlg8aZ6wftBQSFMyYsTflRG9DvHPyi6tkDhrPS53yKZhD1d3+Yv1NQkwm\n 3ILi4UKMT1NeDpKRmrUf4GmO9dMcKfRWYaO4RKTtNo1EcbaDdNm5esm/XTMMgFqFH332\n DCplExzG71Saf3y/mZspW55Vk6xfK48Ki6D4OwOIwybO4in8cU8WLCbOIXGJnzDmZ2Du\n +V2jdgoxYmM6cb5JvTZyU3VUU9Gp8RNdkAdmos49gVCJqO8wEw42Nsn8NHgoA1OkOhJS\n AUK2UYCKO8M0Lf/OW3bCODZFT45R8UdD/cW/3tBfhD5IsirI7vgFvQdaW79JvoZmS83Y\n ICfQ==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777908285; x=1778513085;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=e5SrUHjOSHTBq0/mFBnBMs/u2s9oJydgiRS1iqSgBsU=;\n b=hOFEPgaFAih1HtInRyaw0YTv9SA/oMZH7D3zo75MLpY/9F7fe7jvyeG5KwjbCJHM3z\n Lz9ibkCxRj7G8ZI6if8RIUzN+Q6tZLmmBJOaJSxNSX1SGofCTczpqnGES81CtL5ctl7R\n LrDcvjDS4FBcdjUuo5Ixv+QdqcoKvVgHL15Ie0MVv2IisaWZusW924Sdpe0IM1mmgNXv\n 8amvyujXtgUUSLGKqmw/60M0LtbHZYE1Z6PdWrpQnJSpycw0HJWpKIvICWVWUDLrAlGi\n yybeNSx8IULFrYtwtzm8bb4nR+cb26aGhPMy/OyiSUW8Ej/gggpmweKSn9Zx8ijwQ/xa\n albg==", "X-Gm-Message-State": "AOJu0YzS39eDnpORhxjNo5hHQ6r8eIEMWE/mLzHzmxFFFnmN8AbaF8Vw\n 4/JF4Xt0t6kTjOVMt0aVM8pZTC9LR8O43yxtsgJrb9hvMrT5oeRMHR8QCsBlTw==", "X-Gm-Gg": "AeBDietSL6lC7s96GXyHdrnIIqYW2mNEGUzdONTtIhrpbkQ9dCn9NFPGnGGMktMKj7w\n RAR33Q/70Lf6RZT6osaupTfRrDpj+ZRSz7GLAUag5CDaYCk1TqEN13GTbAFSJCpQDqvJUbJLSS/\n AgIxSfQv6tqAh+jn2j405/eJUYIi4zyNzn6ia64pJGwt4AAVdmdGE8rRtmYa1wbNvolzU3oUGKR\n o2I60MjLLcL4tiTM2lwlYNzzNYNma8ZBnuxtxOe33Za28/YYBQ3oVgdt+uRaQwrNESfZD2Te8WA\n KjbCmoIrCEQyCnxPp8xhVuu9mR3BSLAKHTOiGBYAiFw403VI81d4dQP0DvGSfqsz9NPUaJxBqP/\n FJui97qZsQerdyvtKnytrMtiGPDmupYsCQpmf46GlU5gtNRhYG4Ab5vf7BfjVMn0NFFaK/mUDDp\n X+RfdnkFdk4vpE70uWxyaCcMl+kpm3NdqL+KBaiD+K+1E=", "X-Received": "by 2002:a05:600c:4f8a:b0:48d:46a:6e43 with SMTP id\n 5b1f17b1804b1-48d046a7074mr108783225e9.5.1777908284600;\n Mon, 04 May 2026 08:24:44 -0700 (PDT)", "From": "Disservin <disservin.social@gmail.com>", "To": "gcc-patches@gcc.gnu.org", "Cc": "Disservin <disservin.social@gmail.com>", "Subject": "[PATCH v2] Add __builtin_bitreverse{8,16,32,64} [PR50481]", "Date": "Mon, 4 May 2026 17:23:24 +0200", "Message-Id": "<20260504152323.4034277-1-disservin.social@gmail.com>", "X-Mailer": "git-send-email 2.34.1", "In-Reply-To": "<20260502101755.308183-1-disservin.social@gmail.com>", "References": "<20260502101755.308183-1-disservin.social@gmail.com>", "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}\nbuiltins.\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\ngcc/ChangeLog:\n\t* builtin-types.def (BT_FN_UINT8_UINT8): New.\n\t* builtins.def (BUILT_IN_BITREVERSE8, BUILT_IN_BITREVERSE16,\n\tBUILT_IN_BITREVERSE32, BUILT_IN_BITREVERSE64): New builtins.\n\t* builtins.cc (expand_builtin, is_inexpensive_builtin): Handle\n\tbitreverse builtins.\n\t* fold-const-call.cc (fold_const_call_ss): Fold bitreverse builtins.\n\t* fold-const.cc (tree_call_nonnegative_warnv_p): Handle\n\tbitreverse builtins.\n\t* optabs.def (bitreverse_optab): New.\n\t* optabs.cc (expand_bitreverse): New function.\n\t(expand_unop): Use it for bitreverse_optab.\n\t* tree-ssa-ccp.cc (evaluate_stmt): Handle bitreverse builtins.\n\t* tree-ssa-phiopt.cc (empty_bb_or_one_feeding_into_p,\n\tcond_removal_in_builtin_zero_pattern): Likewise.\n\t* doc/extend.texi: Document __builtin_bitreverse{8,16,32,64}.\n\ngcc/testsuite/ChangeLog:\n\t* gcc.dg/builtin-bitreverse-fold.c: New test.\n\t* gcc.dg/builtin-bitreverse64.c: New test.\n\n---\n\nv2 fix formatting nits\n\ngcc/ChangeLog:\n\t* fold-const-call.cc (fold_const_call_ss): Update formatting nits.\n\t* optabs.cc (expand_bitreverse): Update formatting nits.\n\ngcc/testsuite/ChangeLog:\n\t* gcc.dg/builtin-bitreverse-fold.c: Update compile target to int32.\n\nSigned-off-by: Disservin <disservin.social@gmail.com>\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 | 127 ++++++++++++++++++\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, 223 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 ab0cbc65cfc..365badca2aa 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 692e20088c2..0475bb88a61 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 8ab0599b17f..68838de55f1 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 0faa5323ce1..aa1f526f7fd 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 7dd1b21c34f..d5408f252f7 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\tTYPE_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 56503e570bc..3bc82a108db 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 111b9be9913..46f3a7c9ca1 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 == NULL_RTX\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,10 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,\n goto try_libcall;\n }\n \n+ if (unoptab == bitreverse_optab && is_a <scalar_int_mode> (mode, &int_mode))\n+ if (temp = expand_bitreverse (int_mode, op0, target))\n+\treturn temp;\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 193f42a728a..7ccea18543f 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 00000000000..311fd45263a\n--- /dev/null\n+++ b/gcc/testsuite/gcc.dg/builtin-bitreverse-fold.c\n@@ -0,0 +1,9 @@\n+/* { dg-do compile { target int32 } } */\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 00000000000..8419452ff60\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 952ebf17e7a..974bef17832 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 0bf7e58b8f0..50ddeaa67c1 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": [ "v2" ] }