aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-09-29 12:28:19 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-09-29 12:28:19 +0000
commitda186c1f433028066a476955a36ce48647b13c6b (patch)
treec3cb23c9a8b9f2504891fcb8abfcce79e11b1cd6 /gcc
parentd657e9952231dee084e1ba658dc3462a82504d78 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/match.pd17
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr77407.c18
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" } } */