This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
match.pd patch: u + 3 < u is u > UINT_MAX - 3
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 22 Apr 2016 05:29:57 +0200 (CEST)
- Subject: match.pd patch: u + 3 < u is u > UINT_MAX - 3
- Authentication-results: sourceware.org; auth=none
Hello,
this optimizes a common pattern for unsigned overflow detection, when one
of the arguments turns out to be a constant. There are more ways this
could look like, (a + 42 <= 41) in particular, but that'll be for another
patch.
Bootstrap+regtest on powerpc64le-unknown-linux-gnu.
2016-04-22 Marc Glisse <marc.glisse@inria.fr>
gcc/
* match.pd (X + CST CMP X): New transformation.
gcc/testsuite/
* gcc.dg/tree-ssa/overflow-1.c: New testcase.
--
Marc Glisse
Index: gcc/match.pd
===================================================================
--- gcc/match.pd (revision 235350)
+++ gcc/match.pd (working copy)
@@ -3071,10 +3071,32 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(simplify
/* signbit(x) -> 0 if x is nonnegative. */
(SIGNBIT tree_expr_nonnegative_p@0)
{ integer_zero_node; })
(simplify
/* signbit(x) -> x<0 if x doesn't have signed zeros. */
(SIGNBIT @0)
(if (!HONOR_SIGNED_ZEROS (@0))
(convert (lt @0 { build_real (TREE_TYPE (@0), dconst0); }))))
+
+/* When one argument is a constant, overflow detection can be simplified.
+ Currently restricted to single use so as not to interfere too much with
+ ADD_OVERFLOW detection in tree-ssa-math-opts.c. */
+(for cmp (lt le ge gt)
+ out (gt gt le le)
+ (simplify
+ (cmp (plus@2 @0 integer_nonzerop@1) @0)
+ (if (TYPE_UNSIGNED (TREE_TYPE (@0))
+ && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))
+ && TYPE_MAX_VALUE (TREE_TYPE (@0))
+ && single_use (@2))
+ (out @0 (minus { TYPE_MAX_VALUE (TREE_TYPE (@0)); } @1)))))
+(for cmp (gt ge le lt)
+ out (gt gt le le)
+ (simplify
+ (cmp @0 (plus@2 @0 integer_nonzerop@1))
+ (if (TYPE_UNSIGNED (TREE_TYPE (@0))
+ && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))
+ && TYPE_MAX_VALUE (TREE_TYPE (@0))
+ && single_use (@2))
+ (out @0 (minus { TYPE_MAX_VALUE (TREE_TYPE (@0)); } @1)))))
Index: gcc/testsuite/gcc.dg/tree-ssa/overflow-1.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/overflow-1.c (revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/overflow-1.c (working copy)
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+int f(unsigned a){
+ unsigned b=5;
+ unsigned c=a-b;
+ return c>a;
+}
+int g(unsigned a){
+ unsigned b=32;
+ unsigned c=a+b;
+ return c<a;
+}
+
+/* { dg-final { scan-tree-dump "a_\[0-9\]+.D. <= 4;" "optimized" } } */
+/* { dg-final { scan-tree-dump "a_\[0-9\]+.D. > 4294967263;" "optimized" } } */