This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR77407
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 28 Sep 2016 15:52:25 +0200 (CEST)
- Subject: [PATCH] Fix PR77407
- Authentication-results: sourceware.org; auth=none
The following patch implements patterns to catch x / abs (x)
and x / -x, taking advantage of undefinedness at x == 0 as
opposed to the PR having testcases with explicit != 0 checks.
Bootstrap / regtest pending on x86_64-unknown-linux-gnu.
Richard.
2016-09-28 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.
Index: gcc/match.pd
===================================================================
--- gcc/match.pd (revision 240565)
+++ gcc/match.pd (working copy)
@@ -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. */
Index: gcc/testsuite/gcc.dg/pr77407.c
===================================================================
--- gcc/testsuite/gcc.dg/pr77407.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr77407.c (working copy)
@@ -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" } } */