diff options
author | Richard Biener <rguenther@suse.de> | 2016-09-29 12:28:19 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2016-09-29 12:28:19 +0000 |
commit | da186c1f433028066a476955a36ce48647b13c6b (patch) | |
tree | c3cb23c9a8b9f2504891fcb8abfcce79e11b1cd6 /gcc | |
parent | d657e9952231dee084e1ba658dc3462a82504d78 (diff) | |
download | gcc-da186c1f433028066a476955a36ce48647b13c6b.zip gcc-da186c1f433028066a476955a36ce48647b13c6b.tar.gz gcc-da186c1f433028066a476955a36ce48647b13c6b.tar.bz2 |
re PR middle-end/77407 (Optimize integer i / abs (i) into the sign of i)
2016-09-29 Richard Biener <rguenther@suse.de>
PR middle-end/77407
* match.pd: Add X / abs (X) -> X < 0 ? -1 : 1 and
X / -X -> -1 simplifications.
* gcc.dg/pr77407.c: New testcase.
From-SVN: r240616
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/match.pd | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr77407.c | 18 |
4 files changed, 44 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ebd880..6b832ed 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2016-09-29 Richard Biener <rguenther@suse.de> + PR middle-end/77407 + * match.pd: Add X / abs (X) -> X < 0 ? -1 : 1 and + X / -X -> -1 simplifications. + +2016-09-29 Richard Biener <rguenther@suse.de> + PR middle-end/55152 * match.pd: Add max(a,-a) -> abs(a) pattern. * tree-ssa-phiopt.c (minmax_replacement): Disable for diff --git a/gcc/match.pd b/gcc/match.pd index 553e50d..ba7e013 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -147,12 +147,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (op @0 integer_onep) (non_lvalue @0))) -/* X / -1 is -X. */ (for div (trunc_div ceil_div floor_div round_div exact_div) + /* X / -1 is -X. */ (simplify (div @0 integer_minus_onep@1) (if (!TYPE_UNSIGNED (type)) - (negate @0)))) + (negate @0))) + /* X / abs (X) is X < 0 ? -1 : 1. */ + (simplify + (div @0 (abs @0)) + (if ((INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type)) + && TYPE_OVERFLOW_UNDEFINED (type)) + (cond (lt @0 { build_zero_cst (type); }) + { build_minus_one_cst (type); } { build_one_cst (type); }))) + /* X / -X is -1. */ + (simplify + (div @0 (negate @0)) + (if ((INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type)) + && TYPE_OVERFLOW_UNDEFINED (type)) + { build_minus_one_cst (type); }))) /* For unsigned integral types, FLOOR_DIV_EXPR is the same as TRUNC_DIV_EXPR. Rewrite into the latter in this case. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a88a975..9269d58 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-09-28 Richard Biener <rguenther@suse.de> + + PR middle-end/77407 + * gcc.dg/pr77407.c: New testcase. + 2016-09-29 Richard Biener <rguenther@suse.de> PR middle-end/55152 diff --git a/gcc/testsuite/gcc.dg/pr77407.c b/gcc/testsuite/gcc.dg/pr77407.c new file mode 100644 index 0000000..8cad857 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr77407.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fstrict-overflow -fdump-tree-gimple" } */ + +int foo (int c) +{ + if (c != 0) + c /= __builtin_abs (c); + return c; +} + +int bar (int c) +{ + if (c != 0) + c /= -c; + return c; +} + +/* { dg-final { scan-tree-dump-times "/" 0 "gimple" } } */ |