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

--- Comment #4 from CVS 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:9febe9e4be7812519258ea3ed4f38bbc1a61624b

commit r11-6580-g9febe9e4be7812519258ea3ed4f38bbc1a61624b
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Mon Jan 11 10:34:07 2021 +0100

    widening_mul: Pattern recognize also signed multiplication with overflow
check [PR95852]

    On top of the previous widening_mul patch, this one recognizes also
    (non-perfect) signed multiplication with overflow, like:
    int
    f5 (int x, int y, int *res)
    {
      *res = (unsigned) x * y;
      return x && (*res / x) != y;
    }
    The problem with such checks is that they invoke UB if x is -1 and
    y is INT_MIN during the division, but perhaps the code knows that
    those values won't appear.  As that case is UB, we can do for that
    case whatever we want and handling that case as signed overflow
    is the best option.  If x is a constant not equal to -1, then the checks
    are 100% correct though.
    Haven't tried to pattern match bullet-proof checks, because I really don't
    know if users would write it in real-world code like that,
    perhaps
      *res = (unsigned) x * y;
      return x && (x == -1 ? (*res / y) != x : (*res / x) != y);
    ?

   
https://wiki.sei.cmu.edu/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
    suggests to use twice as wide multiplication (perhaps we should handle that
    too, for both signed and unsigned), or some very large code
    with 4 different divisions nested in many conditionals, no way one can
    match all the possible variants thereof.

    2021-01-11  Jakub Jelinek  <ja...@redhat.com>

            PR tree-optimization/95852
            * tree-ssa-math-opts.c (maybe_optimize_guarding_check): Change
            mul_stmts parameter type to vec<gimple *> &.  Before cond_stmt
            allow in the bb any of the stmts in that vector, div_stmt and
            up to 3 cast stmts.
            (arith_cast_equal_p): New function.
            (arith_overflow_check_p): Add cast_stmt argument, handle signed
            multiply overflow checks.
            (match_arith_overflow): Adjust caller.  Handle signed multiply
            overflow checks.

            * gcc.target/i386/pr95852-3.c: New test.
            * gcc.target/i386/pr95852-4.c: New test.

Reply via email to