On Tue, Oct 6, 2026 at 11:27 PM Jakub Jelinek <[email protected]> wrote:
>
> Hi!
>
> r17-126 has changed the simplification in a way where it can now
> introduce signed integer overflow into a program which didn't have it before,
> e.g. x != (INT_MAX - 3) ? x + 5 : (INT_MIN + 1) when x is int
> doesn't invoke signed integer overflow for x equal to INT_MAX - 3 (it does
> for various other values and for many doesn't), while the simplified
> x + 5 invokes it even for that value.
>
> The following patch fixes it by checking for overflow on the CST1 + CST2
> addition, if TYPE_OVERFLOW_WRAPS or if CST1 + CST2 doesn't overflow,
> it does what it previously did, otherwise rewrites x + CST2 into
> unsigned.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2026-10-07  Jakub Jelinek  <[email protected]>
>
>         PR tree-optimization/126459
>         * match.pd (x != CST1 ? x + CST2 : CST3 -> x + CST2): If
>         CST1 + CST2 overflows and type overflow doesn't wrap,
>         simplify into corresponding unsigned addition.

Ok.

>
>         * gcc.dg/torture/pr126459.c: New test.
>
> --- a/gcc/match.pd      2026-10-03 21:28:13.092320517 +0200
> +++ b/gcc/match.pd      2026-10-06 21:51:21.966900769 +0200
> @@ -5369,9 +5369,16 @@ (define_operator_list SYNC_FETCH_AND_AND
>      tree cst1 = uniform_integer_cst_p (@1);
>      tree cst2 = uniform_integer_cst_p (@3);
>      tree cst3 = uniform_integer_cst_p (@4);
> -  }
> -  (if (wi::to_wide (cst1) + wi::to_wide (cst2) == wi::to_wide (cst3))
> -   @2))))
> +    wi::overflow_type ovf;
> +   }
> +   (if (wi::add (wi::to_wide (cst1), wi::to_wide (cst2),
> +                TYPE_SIGN (TREE_TYPE (cst1)), &ovf) == wi::to_wide (cst3))
> +    (if (!ovf || TYPE_OVERFLOW_WRAPS (TREE_TYPE (cst1)))
> +     @2
> +     (with {
> +       tree utype = unsigned_type_for (type);
> +      }
> +      (convert (plus (convert:utype @0) (convert:utype @3)))))))))
>
>  /* Simplifications of shift and rotates.  */
>
> --- a/gcc/testsuite/gcc.dg/torture/pr126459.c   2026-10-06 22:05:01.595899608 
> +0200
> +++ b/gcc/testsuite/gcc.dg/torture/pr126459.c   2026-10-06 22:04:43.130147484 
> +0200
> @@ -0,0 +1,34 @@
> +/* PR tree-optimization/126459 */
> +/* { dg-do run } */
> +
> +#define INT_MAX __INT_MAX__
> +#define INT_MIN (-(INT_MAX) - 1)
> +
> +__attribute__((noipa)) int
> +foo (int x)
> +{
> +  return (x != INT_MAX ? x + 1 : INT_MIN) > x;
> +}
> +
> +__attribute__((noipa)) int
> +bar (int x)
> +{
> +  return (x != INT_MIN ? x - 1 : INT_MAX) < x;
> +}
> +
> +__attribute__((noipa)) int
> +baz (int x)
> +{
> +  return (x != INT_MIN ? x + INT_MIN : 0) < 0;
> +}
> +
> +int
> +main ()
> +{
> +  if (foo (INT_MAX) != 0 || foo (1) != 1)
> +    __builtin_abort ();
> +  if (bar (INT_MIN) != 0 || bar (2) != 1)
> +    __builtin_abort ();
> +  if (baz (INT_MIN) != 0 || baz (3) != 1)
> +    __builtin_abort ();
> +}
>
>         Jakub
>

Reply via email to