Message ID | Zdw2G2swbBpJJn+w@tucnak |
---|---|
State | New |
Headers | show |
Series | match.pd: Guard 2 simplifications on integral TYPE_OVERFLOW_UNDEFINED [PR114090] | expand |
On Mon, 26 Feb 2024, Jakub Jelinek wrote: > Hi! > > These 2 patterns are incorrect on floating point, or for -fwrapv, or > for -ftrapv, or the first one for unsigned types (the second one is > mathematically correct, but we ought to just fold that to 0 instead). > > So, the following patch properly guards this. > > I think we don't need && !TYPE_OVERFLOW_SANITIZED (type) because > in both simplifications there would be UB before and after on > signed integer minimum. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? OK. Thanks, Richard. > 2024-02-26 Jakub Jelinek <jakub@redhat.com> > > PR tree-optimization/114090 > * match.pd ((x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x): > Restrict pattern to ANY_INTEGRAL_TYPE_P and TYPE_OVERFLOW_UNDEFINED > types. > ((x <= 0 ? -x : 0) -> max(-x, 0)): Likewise. > > * gcc.dg/pr114090.c: New test. > > --- gcc/match.pd.jj 2024-02-22 10:09:48.678446435 +0100 > +++ gcc/match.pd 2024-02-24 19:23:32.201014245 +0100 > @@ -453,8 +453,9 @@ (define_operator_list SYNC_FETCH_AND_AND > > /* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x. */ > (simplify > - (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop)) > - (abs @0)) > + (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop)) > + (if (ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_UNDEFINED (type)) > + (abs @0))) > > /* X * 1, X / 1 -> X. */ > (for op (mult trunc_div ceil_div floor_div round_div exact_div) > @@ -4218,8 +4219,9 @@ (define_operator_list SYNC_FETCH_AND_AND > > /* (x <= 0 ? -x : 0) -> max(-x, 0). */ > (simplify > - (cond (le @0 integer_zerop@1) (negate@2 @0) integer_zerop@1) > - (max @2 @1)) > + (cond (le @0 integer_zerop@1) (negate@2 @0) integer_zerop@1) > + (if (ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_UNDEFINED (type)) > + (max @2 @1))) > > /* (zero_one == 0) ? y : z <op> y -> ((typeof(y))zero_one * z) <op> y */ > (for op (bit_xor bit_ior plus) > --- gcc/testsuite/gcc.dg/pr114090.c.jj 2024-02-24 19:38:56.301096850 +0100 > +++ gcc/testsuite/gcc.dg/pr114090.c 2024-02-24 19:42:26.917153801 +0100 > @@ -0,0 +1,38 @@ > +/* PR tree-optimization/114090 */ > +/* { dg-do run } */ > +/* { dg-options "-O2 -fwrapv" } */ > + > +__attribute__((noipa)) int > +foo (int x) > +{ > + int w = (x >= 0 ? x : 0); > + int y = -x; > + int z = (y >= 0 ? y : 0); > + return w + z; > +} > + > +__attribute__((noipa)) int > +bar (int x) > +{ > + int w = (x >= 0 ? x : 0); > + int z = (x <= 0 ? -x : 0); > + return w + z; > +} > + > +__attribute__((noipa)) int > +baz (int x) > +{ > + return x <= 0 ? -x : 0; > +} > + > +int > +main () > +{ > + int v = -__INT_MAX__ - 1; > + if (foo (v) != 0) > + __builtin_abort (); > + if (bar (v) != v) > + __builtin_abort (); > + if (baz (v) != v) > + __builtin_abort (); > +} > > Jakub > >
--- gcc/match.pd.jj 2024-02-22 10:09:48.678446435 +0100 +++ gcc/match.pd 2024-02-24 19:23:32.201014245 +0100 @@ -453,8 +453,9 @@ (define_operator_list SYNC_FETCH_AND_AND /* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x. */ (simplify - (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop)) - (abs @0)) + (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop)) + (if (ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_UNDEFINED (type)) + (abs @0))) /* X * 1, X / 1 -> X. */ (for op (mult trunc_div ceil_div floor_div round_div exact_div) @@ -4218,8 +4219,9 @@ (define_operator_list SYNC_FETCH_AND_AND /* (x <= 0 ? -x : 0) -> max(-x, 0). */ (simplify - (cond (le @0 integer_zerop@1) (negate@2 @0) integer_zerop@1) - (max @2 @1)) + (cond (le @0 integer_zerop@1) (negate@2 @0) integer_zerop@1) + (if (ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_UNDEFINED (type)) + (max @2 @1))) /* (zero_one == 0) ? y : z <op> y -> ((typeof(y))zero_one * z) <op> y */ (for op (bit_xor bit_ior plus) --- gcc/testsuite/gcc.dg/pr114090.c.jj 2024-02-24 19:38:56.301096850 +0100 +++ gcc/testsuite/gcc.dg/pr114090.c 2024-02-24 19:42:26.917153801 +0100 @@ -0,0 +1,38 @@ +/* PR tree-optimization/114090 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fwrapv" } */ + +__attribute__((noipa)) int +foo (int x) +{ + int w = (x >= 0 ? x : 0); + int y = -x; + int z = (y >= 0 ? y : 0); + return w + z; +} + +__attribute__((noipa)) int +bar (int x) +{ + int w = (x >= 0 ? x : 0); + int z = (x <= 0 ? -x : 0); + return w + z; +} + +__attribute__((noipa)) int +baz (int x) +{ + return x <= 0 ? -x : 0; +} + +int +main () +{ + int v = -__INT_MAX__ - 1; + if (foo (v) != 0) + __builtin_abort (); + if (bar (v) != v) + __builtin_abort (); + if (baz (v) != v) + __builtin_abort (); +}