]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-ssa-ccp: Fix up __builtin_bitreverse* handling [PR50481]
authorJakub Jelinek <jakub@redhat.com>
Sat, 16 May 2026 08:50:00 +0000 (10:50 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sat, 16 May 2026 08:50:00 +0000 (10:50 +0200)
The committed __builtin_bitreverse* patch mishandled the
bitwise CCP handling, it is true that BUILT_IN_BITREVERSE* can be
handled there similarly to BUILT_IN_BSWAP*, but not exactly, for
the latter we need (and do) bswap the value and mask constants,
while for the former we obviously need to bitreverse them instead.

2026-05-16  Jakub Jelinek  <jakub@redhat.com>

PR target/50481
* tree-ssa-ccp.cc (evaluate_stmt): Fix up
BUILT_IN_BITREVERSE{8,16,32,64} handling.

* gcc.dg/builtin-bitreverse-3.c: New test.

Reviewed-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
gcc/testsuite/gcc.dg/builtin-bitreverse-3.c [new file with mode: 0644]
gcc/tree-ssa-ccp.cc

diff --git a/gcc/testsuite/gcc.dg/builtin-bitreverse-3.c b/gcc/testsuite/gcc.dg/builtin-bitreverse-3.c
new file mode 100644 (file)
index 0000000..bd56012
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#if __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8
+[[gnu::noipa]] bool
+foo (unsigned x)
+{
+  x &= 0x499a750a;
+  x |= 0x5a7c04f;
+  x = __builtin_bitreverse32 (x);
+  return (x & ~0x351848) == 0x4fc0a705;
+}
+
+[[gnu::noipa]] bool
+bar (unsigned x)
+{
+  x &= 0x499a750a;
+  x |= 0x5a7c04f;
+  x = __builtin_bitreverse32 (x);
+  return (x & ~0xac1812) == 0xf203e5a0;
+}
+#endif
+
+int
+main ()
+{
+#if __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8
+  if (foo (~0) || !bar (~0))
+    __builtin_abort ();
+#endif
+}
index 974bef17832f01fb7534f70a61f34c715558d339..891fcc12cafc3be21cce59b96410992d1a0fbbe2 100644 (file)
@@ -2435,10 +2435,6 @@ evaluate_stmt (gimple *stmt)
            case BUILT_IN_BSWAP32:
            case BUILT_IN_BSWAP64:
            case BUILT_IN_BSWAP128:
-           case BUILT_IN_BITREVERSE8:
-           case BUILT_IN_BITREVERSE16:
-           case BUILT_IN_BITREVERSE32:
-           case BUILT_IN_BITREVERSE64:
              val = get_value_for_expr (gimple_call_arg (stmt, 0), true);
              if (val.lattice_val == UNDEFINED)
                break;
@@ -2466,6 +2462,33 @@ evaluate_stmt (gimple *stmt)
              val.mask = -1;
              break;
 
+           case BUILT_IN_BITREVERSE8:
+           case BUILT_IN_BITREVERSE16:
+           case BUILT_IN_BITREVERSE32:
+           case BUILT_IN_BITREVERSE64:
+             val = get_value_for_expr (gimple_call_arg (stmt, 0), true);
+             if (val.lattice_val == UNDEFINED)
+               break;
+             else if (val.lattice_val == CONSTANT
+                      && val.value
+                      && TREE_CODE (val.value) == INTEGER_CST)
+               {
+                 tree type = TREE_TYPE (gimple_call_lhs (stmt));
+                 int prec = TYPE_PRECISION (type);
+                 wide_int wval = wi::to_wide (val.value);
+                 wval = wide_int::from (wval, prec, UNSIGNED);
+                 wide_int wmask = wide_int::from (val.mask, prec, UNSIGNED);
+                 val.value = wide_int_to_tree (type, wi::bitreverse (wval));
+                 val.mask = widest_int::from (wi::bitreverse (wmask),
+                                              UNSIGNED);
+                 if (wi::sext (val.mask, prec) != -1)
+                   break;
+               }
+             val.lattice_val = VARYING;
+             val.value = NULL_TREE;
+             val.mask = -1;
+             break;
+
            default:;
            }
        }