match.pd: Guard 2 simplifications on integral TYPE_OVERFLOW_UNDEFINED [PR114090]
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. 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.
This commit is contained in:
parent
f9d2a95be5
commit
24aa051af7
2 changed files with 44 additions and 4 deletions
10
gcc/match.pd
10
gcc/match.pd
|
@ -453,8 +453,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
|||
|
||||
/* (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_INT_AND_FLOAT_ROUND_FN (RINT)
|
|||
|
||||
/* (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)
|
||||
|
|
38
gcc/testsuite/gcc.dg/pr114090.c
Normal file
38
gcc/testsuite/gcc.dg/pr114090.c
Normal file
|
@ -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 ();
|
||||
}
|
Loading…
Add table
Reference in a new issue