Re: [PATCH v2 1/2] match: Fix recent pattern for signed integer overflow dealing with - [PR126418]

Richard Biener <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <CAFiYyc0jY+ig+ionJDPK0PeQ3kTv8625dro3xNEoDqN8RmxdZw@mail.gmail.com>
On Wed, Aug 12, 2026 at 5:06 AM Andrea Pinski
<[email protected]> wrote:
>
> A recent match patterns were added that introduce signed integer overflow where
> there was none before.  `cmp + (-cmp ^ x)` has no signed integer overflow when
> x is INT_MIN when cmp is 0. This gets translated into cmp ? -x : x.
> But this has now introduced an signed integer overflow for INT_MIN.
> The fix is to use unsigned type for the negative.
>
> Bootstrapped and tested on x86_64-linux-gnu.

OK.

I've commented on 2/2 in v1.

> Changes since v1:
> * v2: Remove the abs patterns since a signed integer overflow would have happened anyways.
>
>         PR tree-optimization/126418
>
> gcc/ChangeLog:
>
>         * match.pd (`(A ^ -cmp) + cmp`): Cast to unsigned type
>         before taking the negative.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/pr126418-1.c: New test.
>
> Signed-off-by: Andrea Pinski <[email protected]>
> ---
>  gcc/match.pd                               |  8 +++++++-
>  gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c | 11 +++++++++++
>  2 files changed, 18 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 5da1e372f10..945fcabf956 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -4942,7 +4942,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>   (if (INTEGRAL_TYPE_P (type)
>        && !TYPE_SATURATING (type)
>        && (GIMPLE || !TREE_SIDE_EFFECTS (@0)))
> -  (cond (convert:boolean_type_node @1) (negate @0) @0)))
> +  /* Do the negate in unsigned type always; otherwise
> +     we would be introducing an overflow.  */
> +  (with { tree utype = unsigned_type_for (type); }
> +   (cond
> +    (convert:boolean_type_node @1)
> +    (convert:type (negate (convert:utype @0)))
> +    @0))))
>
>  /* Transform A & (B*cmp) into (A&B)*cmp.  */
>  (simplify
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c
> new file mode 100644
> index 00000000000..3714069b43f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-forwprop1" } */
> +
> +int f_cmp_gt_commuted(int x, int y)
> +{
> +  int cmp = x > y;
> +  return cmp + (-cmp ^ x);
> +}
> +
> +/* { dg-final { scan-tree-dump-times "\\(unsigned int\\) " 1 "forwprop1" } } */
> +/* { dg-final { scan-tree-dump-times "\\(int\\) " 1 "forwprop1" } } */
> --
> 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.