Re: [PATCH v2] match: Try to remove casts for `(int)-(unsigned)a`[PR107765]

Richard Biener <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <CAFiYyc04pQLQSrN3Z--0=Tywr0DNYz-uvT70LgHzuQJ2KOOoyw@mail.gmail.com>
On Fri, Aug 14, 2026 at 8:21 AM Andrea Pinski
<[email protected]> wrote:
>
> This adds some extra checks to see if we can remove the casts
> for signed integer overflow reasons while doing a negative.
> This is needed more due to the recent patch which adds them
> in some cases.
>
> This also changes TYPE_UNSIGNED to be TYPE_OVERFLOW_WRAPS to
> allow this to happen with -fwrapv too.
>
> Changes since v1:
> * Use expr_not_equal_to and simplify the if stmt.
> Also use TYPE_OVERFLOW_WRAPS instead of TYPE_UNSIGNED.
>
> Bootstrapped and tested on x86_64-linux-gnu.

OK.

>         PR tree-optimization/107765
>
> gcc/ChangeLog:
>
>         * match.pd (`(cast)-(cast)a`): Expand to
>         use expr_not_equal_to of INT_MIN.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/neg-cast-1.c: New test.
>         * gcc.dg/tree-ssa/neg-cast-4.c: New test.
>
> Signed-off-by: Andrea Pinski <[email protected]>
> ---
>  gcc/match.pd                               | 10 +++++++---
>  gcc/testsuite/gcc.dg/tree-ssa/neg-cast-1.c | 23 ++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/neg-cast-4.c | 16 +++++++++++++++
>  3 files changed, 46 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/neg-cast-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/neg-cast-4.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 4631e811108..30657fa5bae 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -1231,13 +1231,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>     show up.  Else it is safe if the negation is done in an unsigned type.
>     Note the outer cast cannot be a boolean type as the only valid values
>     are 0,-1/1 (depending on the signedness of the boolean) and the negative
> -   is there to get the correct value.  */
> +   is there to get the correct value.
> +   Also handle the case where we know that we won't cause a signed
> +   integer overflow at the point of the negation.  */
>  (simplify
> - (convert (negate:s@1 (convert:s @0)))
> + (convert (negate:s@1 (convert:s@ic @0)))
>   (if (INTEGRAL_TYPE_P (type)
>        && tree_nop_conversion_p (type, TREE_TYPE (@1))
>        && (TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0))
> -         || TYPE_UNSIGNED (type))
> +         || TYPE_OVERFLOW_WRAPS (type)
> +         || expr_not_equal_to (@ic, wi::min_value (signed_type_for (type)),
> +                               gimple_match_ctx (@1)))
>        && TREE_CODE (type) != BOOLEAN_TYPE)
>      (negate (convert @0))))
>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/neg-cast-1.c b/gcc/testsuite/gcc.dg/tree-ssa/neg-cast-1.c
> new file mode 100644
> index 00000000000..ec5d0e15251
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/neg-cast-1.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-cddce1" } */
> +/* PR tree-optimization/107765 */
> +
> +int a(int input)
> +{
> +    if (input == -__INT_MAX__-1) return 1;
> +    unsigned t = input;
> +    int tt =  -t;
> +    return tt == -input;
> +}
> +
> +int b(int input)
> +{
> +    if (input == -__INT_MAX__-1) __builtin_trap();
> +    unsigned t = input;
> +    int tt =  -t;
> +    return tt;
> +}
> +
> +/* { dg-final { scan-tree-dump "return 1" "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "\\(unsigned int\\)" "cddce1" } } */
> +/* { dg-final { scan-tree-dump-not "\\(int\\)" "cddce1" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/neg-cast-4.c b/gcc/testsuite/gcc.dg/tree-ssa/neg-cast-4.c
> new file mode 100644
> index 00000000000..fe3fe6a2ecc
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/neg-cast-4.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-phiopt2-details -fdump-tree-optimized" } */
> +/* PR tree-optimization/107765 */
> +
> +int b(int input)
> +{
> +    if (input == -__INT_MAX__-1) return input;
> +    unsigned t = input;
> +    int tt =  -t;
> +    return tt;
> +}
> +
> +/* { dg-final { scan-tree-dump-not "if " "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "\\(unsigned int\\)" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "\\(int\\)" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "converted to straightline code" 1 "phiopt2" } } */
> --
> 2.43.0
>
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.