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

--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Richard Biener <[email protected]>:

https://gcc.gnu.org/g:7a3878019f77ec4a41ca31ee8a09f7da6ab92470

commit r17-5023-g7a3878019f77ec4a41ca31ee8a09f7da6ab92470
Author: Richard Biener <[email protected]>
Date:   Fri Oct 9 12:35:52 2026 +0200

    Do not strip conversions on bit test masks in ifcombine

    In recognize_bits_test, get_name_for_bit_test was unconditionally called
    on gimple_assign_rhs1 of the BIT_AND_EXPR.  Because bitwise AND is
    commutative, rhs1 is not necessarily the name being tested; when testing
    a variable against a non-constant mask, rhs1 may be the mask rather than
    the tested value.

    When rhs1 was a mask defined by a single-use narrowing conversion (such as
    m = (int) mm), get_name_for_bit_test stripped the conversion and returned
    the wider variable (e.g. mm).  If the subsequent matching in
    ifcombine_ifandif then matched the other operand with the other
    condition's tested variable via a commutativity swap, the stripped operand
    was swapped into the mask position.  Because the mask had a wider type
    than the tested variable, ifcombine widened the tested variable (e.g.
    (unsigned long) y) and bitwise-ORed the masks together.  This resurrected
    upper bits from the wider variable that had been explicitly truncated in
    the original program, leading to wrong code when the tested variable
    sign-extended into those bit positions.

    Fix this by having recognize_bits_test return the raw operands of the
    BIT_AND_EXPR.  In ifcombine_ifandif, first attempt to match the operands
    directly under commutativity.  Only if that fails, look through
    conversions on the two names, so that a stripped operand never becomes
    part of the combined mask.  Looking through conversions of the names is
    valid for arbitrary masks since the name is truncated and the masks are
    zero-extended to the common type.

            PR tree-optimization/126563
            * tree-ssa-ifcombine.cc (recognize_bits_test): Do not call
            get_name_for_bit_test on rhs1.
            (ifcombine_ifandif): Check all operands for abnormal PHIs.
            Look through conversions via get_name_for_bit_test on the names
            only when direct matching fails.

            * gcc.dg/tree-ssa/ssa-ifcombine-14.c: New test.
            * gcc.dg/tree-ssa/ssa-ifcombine-15.c: New test.

Reply via email to