https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126504

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
It is not dup.  We have other patterns which have this bug (why 4 of them is
unclear to me).

2026-07-30  Jakub Jelinek  <[email protected]>

        PR tree-optimization/126504
        * match.pd ((CST1 << A) == CST2 -> A == ctz (CST2) - ctz (CST1)):
        If cand isn't representable in TREE_TYPE (@1), simplify to
        cmp == NE_EXPR.
        (((1 << n) & M) != 0  -> n == log2 (M)): Don't simplify if
        log2 doesn't fit into TREE_TYPE (@0).

        * gcc.dg/torture/bitint-105.c: New test.

--- gcc/match.pd.jj     2026-07-30 18:03:24.184957827 +0200
+++ gcc/match.pd        2026-07-30 17:58:00.083878442 +0200
@@ -5296,7 +5296,9 @@ (define_operator_list SYNC_FETCH_AND_AND
   (with { int cand = wi::ctz (wi::to_wide (@2)) - wi::ctz (wi::to_wide (@0));
}
    (if (cand < 0
        || (!integer_zerop (@2)
-           && wi::lshift (wi::to_wide (@0), cand) != wi::to_wide (@2)))
+           && wi::lshift (wi::to_wide (@0), cand) != wi::to_wide (@2))
+       || !wi::fits_to_tree_p (wi::shwi (cand, HOST_BITS_PER_INT),
+                               TREE_TYPE (@1)))
     { constant_boolean_node (cmp == NE_EXPR, type); }
     (if (!integer_zerop (@2)
         && wi::lshift (wi::to_wide (@0), cand) == wi::to_wide (@2))
@@ -5444,8 +5446,9 @@ (define_operator_list SYNC_FETCH_AND_AND
    (bit_and
     (nop_convert? (lshift integer_onep @0)) integer_pow2p@1) integer_zerop)
   (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))
-   (icmp @0 { wide_int_to_tree (TREE_TYPE (@0),
-                               wi::exact_log2 (wi::to_wide (@1))); }))))
+   (with { int c = wi::exact_log2 (wi::to_wide (@1)); }
+    (if (wi::fits_to_tree_p (wi::shwi (c, HOST_BITS_PER_INT), TREE_TYPE (@0)))
+     (icmp @0 { wide_int_to_tree (TREE_TYPE (@0), c); }))))))

 /* Fold (X {&,^,|} C2) << C1 into (X << C1) {&,^,|} (C2 << C1)
    (X {&,^,|} C2) >> C1 into (X >> C1) & (C2 >> C1).  */
--- gcc/testsuite/gcc.dg/torture/bitint-105.c.jj        2026-07-30
18:03:55.416580020 +0200
+++ gcc/testsuite/gcc.dg/torture/bitint-105.c   2026-07-30 18:01:55.022036419
+0200
@@ -0,0 +1,24 @@
+/* PR tree-optimization/126504 */
+/* { dg-do run { target bitint } } */
+
+typedef unsigned _BitInt(4) U;
+
+[[gnu::noipa]] int
+foo (U n)
+{
+  return ((1 << n) & (1 << 20)) != 0;
+}
+
+[[gnu::noipa]] int
+bar (U n)
+{
+  return ((unsigned) (1 << n) & (1u << 20)) != 0;
+}
+
+int
+main ()
+{
+  for (unsigned i = 0; i < 16; i++)
+    if (foo (i) || bar (i))
+      __builtin_abort ();
+}

Reply via email to