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

--- Comment #4 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

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

commit r15-5723-ga2370cc4f47fa7f1b2c72135ee1685551c2e25f4
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Wed Nov 27 14:32:07 2024 +0100

    match.pd: Avoid introducing UB in the ((X /[ex] C1) +- C2) * (C1 * C3)
simplification [PR117692]

    As the pr117692.c testcase shows, the generalized pattern can introduce
    UB when there wasn't any.
    The old pattern was I believe correct, it is as if in the new
    pattern C3 was always 1 and I don't see how that could have introduced
    UB.
    But if type is signed and C3 (aka factor) isn't 1 and for + X and C2
    could have different sign or for - X and C2 could have the same sign,
    when doing the addition/subtraction first the absolute value could
    decrease, while if first multiplying by C3 we could invoke UB already
    during that multiplication.

    The following patch fixes it by going through the casts to utype if
    ranger (get_range_pos_neg) detects the sign compared to sign of C2
    (INTEGER_CST) could be the same or could be different depending on op
    because then the absolute value will not increase.

    Other possibility (perhaps as another check if this check doesn't succeed)
    would be to test whether X * C3 could actually overflow.
    vr-values.cc has check_for_binary_op_overflow (currently not exported)
    which I think does what we'd need to check, if it returns true and sets
    ovf to false.

    2024-11-27  Jakub Jelinek  <ja...@redhat.com>

            PR tree-optimization/117692
            * tree.cc (get_range_pos_neg): Adjust function comment, use
            non-negative instead of positive.
            * match.pd
            (((X /[ex] C1) +- C2) * (C1 * C3) -> (X * C3) +- (C1 * C2 * C3)):
            Use casts to utype if type is signed, factor isn't 1 and
            C1 and C2 could have different sign for + or could have the
            same sign for -.

            * gcc.dg/tree-ssa/mulexactdiv-5.c: Expect 8 nop_exprs.
            * gcc.dg/tree-ssa/pr117692.c: New test.

Reply via email to