[Bug tree-optimization/126476] Wrong code with bitint shifts

cvs-commit at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sat Aug 1 10:16:59 GMT 2026


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

--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-15 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:4df1f4c153e31680d4c18dcf6760154e9e34b9aa

commit r15-11442-g4df1f4c153e31680d4c18dcf6760154e9e34b9aa
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Jul 31 08:53:52 2026 +0200

    match.pd: Fix up ((C << A) & D) != 0 simplification [PR126476]

    This simplification for power of two @1 and @2 folds to false (resp.
    to true for the == version) if @1 is larger than @2 (in unsigned
    comparison), because @1 & @2 is known to be zero (i.e. for shift count 0)
    and for shift count larger than that it will be zero too, either because
    @1 << @0 is even larger, or if @0 is too large @1 << @0 overflows to zero.
    This is the case of e.g. ((4 << x) & 2) != 0, which is always false.
    Now, this PR is about a different problem, if @1 is smaller than @2, say
    ((1 << x) & 256) != 0, but x has a very narrow type, say unsigned
_BitInt(3),
    then the largest possible value of x is 7 and ((1 << 7) & 256) is
    still 0, 1 << 7 is 128 and so still smaller than 256.
    So, if c1 - c2 doesn't fit into the shift count type
    (resp. for the other case c2 - c1), it will be also always false (resp.
    true).
    Trying to improve it and using range of x (aka @0) is not needed,
    this simplification folds it into @0 != (c1 - c2) and so will be folded
    later.  Just the case where c1 - c2 overflows is problematic because
    we've lost the details (unless we'd promote both operands or something).
    Another possible way to do this would be build_int_cst and check for
    the overflow flags, but I think this is shorter.

    2026-07-31  Jakub Jelinek  <jakub@redhat.com>

            PR tree-optimization/126476
            * match.pd (((C << A) & D) != 0 -> A == 0,
            ((C << A) & D) == 0 -> A != 0): Fold to false/true if
            c1 - c2 resp. c2 - c1 doesn't fit into TREE_TYPE (@0).

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

    Reviewed-by: Richard Biener <rguenth@suse.de>
    (cherry picked from commit 5c62a2771f2c7d5301ee6456f1817098c2fea113)


More information about the Gcc-bugs mailing list