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

--- Comment #8 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:7bbe3670947e1901435763690f75049ff089b266

commit r17-5024-g7bbe3670947e1901435763690f75049ff089b266
Author: Richard Biener <[email protected]>
Date:   Fri Oct 9 12:05:41 2026 +0200

    Reject merging compares that test the same bit differently

    In fold_truth_andor_for_ifcombine, when combining comparisons between
    two non-constant variables or fields, each compare tests, for every bit
    in its masks, either that the bits on both sides are equal (the bit is
    in both masks), or that the bit on one side is zero (the bit is in only
    one of the masks).  The combined compare can only express one such test
    per bit, but we did not check that both compares agreed on what to test
    for bits they both covered.

    E.g., d1 == (d2 & 32767) tests that bit 15 of d1 is zero, whereas
    (d2 ^ d1) >= 0 tests that bit 15 of d1 and d2 are equal.  Both combined
    masks then covered all 16 bits, and the two comparisons were folded
    into d2 == d1, losing the zero-check on d1's sign bit and miscompiling
    cases where both d1 and d2 were negative (e.g. d1 = d2 = -32768).

    Fix this by rejecting the combination if any bit covered by both
    compares is tested in different ways.  Compares with different masks on
    each side are still combined when they don't conflict, e.g. when the
    fields don't overlap.

            PR tree-optimization/127521
            * gimple-fold.cc (fold_truth_andor_for_ifcombine): Reject
            non-constant compares that test the same bit in different ways.

            * gcc.dg/field-merge-30.c: New test.
            * gcc.dg/field-merge-31.c: New test.

Reply via email to