This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

X /[ex] 4 < Y /[ex] 4


Hello,

we were missing this simplification on comparisons. Note that the testcase
still does not simplify as much as one might like, we don't turn x+z<y+z
into x<y. I'll try to add that next, but the interaction with
Wstrict-overflow may be painful... The goal is that comparing size and
capacity of a std::vector should turn into a simple comparison of the end
pointers.

I am only handling positive constants, because that's all we currently
have with exact division, we can revisit this place and many others when
that changes.

As usual, this might increase register pressure a bit in some cases, I
could ask that at least one of the quotients be single_use if you believe
that's better.

Bootstrap+regtest on powerpc64le-unknown-linux-gnu.

2017-04-24  Marc Glisse  <marc.glisse@inria.fr>

gcc/
	* match.pd (X/[ex]C CMP Y/[ex]C): New transformation.

gcc/testsuite/
	* gcc.dg/tree-ssa/cmpexactdiv-2.c: New file.

--
Marc Glisse
Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 247083)
+++ gcc/match.pd	(working copy)
@@ -1028,20 +1028,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (simplify
   (cmp (mult:c @0 @1) (mult:c @2 @1))
   (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
        && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
    (if (tree_expr_nonnegative_p (@1) && tree_expr_nonzero_p (@1))
     (cmp @0 @2)
    (if (TREE_CODE (@1) == INTEGER_CST
 	&& wi::neg_p (@1, TYPE_SIGN (TREE_TYPE (@1))))
     (cmp @2 @0))))))
 
+/* X / 4 < Y / 4 iif X < Y when the division is known to be exact.  */
+(for cmp (simple_comparison)
+ (simplify
+  (cmp (exact_div @0 INTEGER_CST@2) (exact_div @1 @2))
+  (if (wi::gt_p(@2, 0, TYPE_SIGN (TREE_TYPE (@2))))
+   (cmp @0 @1))))
+
 /* ((X inner_op C0) outer_op C1)
    With X being a tree where value_range has reasoned certain bits to always be
    zero throughout its computed value range,
    inner_op = {|,^}, outer_op = {|,^} and inner_op != outer_op
    where zero_mask has 1's for all bits that are sure to be 0 in
    and 0's otherwise.
    if (inner_op == '^') C0 &= ~C1;
    if ((C0 & ~zero_mask) == 0) then emit (X outer_op (C0 outer_op C1)
    if ((C1 & ~zero_mask) == 0) then emit (X inner_op (C0 outer_op C1)
 */
Index: gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv-2.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv-2.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv-2.c	(working copy)
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized-raw" } */
+
+int f (long *a, long *b, long *c) {
+    __PTRDIFF_TYPE__ l1 = b - a;
+    __PTRDIFF_TYPE__ l2 = c - a;
+    return l1 < l2;
+}
+
+/* Eventually we also want to remove all minus_expr.  */
+/* { dg-final { scan-tree-dump-not "exact_div_expr" "optimized" } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]