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

"cvs-commit at gcc dot gnu.org via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126476

--- Comment #4 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-16 branch has been updated by Jakub Jelinek
<[email protected]>:

https://gcc.gnu.org/g:ec33d63beddc5ba8fc7618792ccef13bd2fb8bc1

commit r16-9474-gec33d63beddc5ba8fc7618792ccef13bd2fb8bc1
Author: Jakub Jelinek <[email protected]>
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  <[email protected]>

            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 <[email protected]>
    (cherry picked from commit 5c62a2771f2c7d5301ee6456f1817098c2fea113)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.