diff --git a/gcc/match.pd b/gcc/match.pd index f059b477f58..5d71a4f907c 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -242,6 +242,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (mult @0 integer_zerop@1) @1) +/* -x == x -> x == 0 */ +(for cmp (eq ne) + (simplify + (cmp:c @0 (negate @0)) + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && !TYPE_OVERFLOW_WRAPS (TREE_TYPE(@0))) + (cmp @0 { build_zero_cst (TREE_TYPE(@0)); })))) + /* Maybe fold x * 0 to 0. The expressions aren't the same when x is NaN, since x * 0 is also NaN. Nor are they the same in modes with signed zeros, since multiplying a diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96779-disabled.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96779-disabled.c new file mode 100644 index 00000000000..205133d8e0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96779-disabled.c @@ -0,0 +1,84 @@ +/* PR tree-optimization/96779 */ +/* { dg-do run } */ +/* { dg-options "-O -fdump-tree-optimized -fwrapv" } */ + +#include + +bool __attribute__ ((noipa)) f_func(int a) +{ + return -a == a; +} + +bool __attribute__ ((noipa)) g_func(unsigned int a) +{ + return -a == a; +} + +bool __attribute__ ((noipa)) h_func(short a) +{ + return -a == a; +} + +bool __attribute__ ((noipa)) k_func(long a) +{ + return -a == a; +} + +int +main (void) +{ + // few randomly generated test cases + if (f_func (71856034)) + { + __builtin_abort (); + } + if (g_func (71856034)) + { + __builtin_abort (); + } + if (h_func (1744)) + { + __builtin_abort (); + } + if (k_func (68268386)) + { + __builtin_abort (); + } + if (f_func (-112237)) + { + __builtin_abort (); + } + if (g_func (-787116)) + { + __builtin_abort (); + } + if (h_func (-863)) + { + __builtin_abort (); + } + if (k_func (-787116)) + { + __builtin_abort (); + } + if (!f_func (0)) + { + __builtin_abort (); + } + if (!g_func (0)) + { + __builtin_abort (); + } + if (!h_func (0)) + { + __builtin_abort (); + } + if (!k_func (0)) + { + __builtin_abort (); + } + + return 0; +} + +/* Verify that we have *not* transfered "= -" pattern in any of those functions. */ +/* { dg-final { scan-tree-dump-times "= -" 4 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96779.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96779.c new file mode 100644 index 00000000000..0d46e8eeb15 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96779.c @@ -0,0 +1,79 @@ +/* PR tree-optimization/96779 */ +/* { dg-do run } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +#include + +bool __attribute__ ((noipa)) f_func(int a) +{ + return -a == a; +} + +bool __attribute__ ((noipa)) h_func(short a) +{ + return -a == a; +} + +bool __attribute__ ((noipa)) k_func(long a) +{ + return -a == a; +} + +int +main (void) +{ + // few randomly generated test cases + if (f_func (71856034)) + { + __builtin_abort (); + } + if (f_func (71856034)) + { + __builtin_abort (); + } + if (h_func (1744)) + { + __builtin_abort (); + } + if (k_func (68268386)) + { + __builtin_abort (); + } + if (f_func (-112237)) + { + __builtin_abort (); + } + if (f_func (-787116)) + { + __builtin_abort (); + } + if (h_func (-863)) + { + __builtin_abort (); + } + if (k_func (-787116)) + { + __builtin_abort (); + } + if (!f_func (0)) + { + __builtin_abort (); + } + if (!f_func (0)) + { + __builtin_abort (); + } + if (!h_func (0)) + { + __builtin_abort (); + } + if (!k_func (0)) + { + __builtin_abort (); + } + + return 0; +} + +/* Verify that we transfered to "= -" pattern from "_2 = -_1;". */ +/* { dg-final { scan-tree-dump-not "= -" "optimized" } } */