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]

Generalize a<b&a<c -> a<min(b,c)


Hello,

this transformation was lacking symmetry, only handling & and not |.

It probably still fails to handle a < b & a <= 123, while it would handle < 124, but that's for another day.

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

2018-05-01  Marc Glisse  <marc.glisse@inria.fr>

	PR tree-optimization/85143
gcc/
	* match.pd (A<B&A<C): Extend to BIT_IOR_EXPR.

gcc/testsuite/
	* gcc.dg/tree-ssa/minmax-loopend.c: Extend and split...
	* gcc.dg/tree-ssa/minmax-loopend-2.c: ... here.

--
Marc Glisse
Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 259767)
+++ gcc/match.pd	(working copy)
@@ -4507,24 +4507,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 		       true, TYPE_PRECISION (type))) == 0)
    (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
     (with { tree ntype = TREE_TYPE (@0); }
      (convert (bit_and (op @0 @1) (convert:ntype @4))))
     (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
      (convert (bit_and (op (convert:utype @0) (convert:utype @1))
 	       (convert:utype @4))))))))
 
 /* Transform (@0 < @1 and @0 < @2) to use min, 
    (@0 > @1 and @0 > @2) to use max */
-(for op (lt le gt ge)
-     ext (min min max max)
+(for logic (bit_and bit_and bit_and bit_and bit_ior bit_ior bit_ior bit_ior)
+     op    (lt      le      gt      ge      lt      le      gt      ge     )
+     ext   (min     min     max     max     max     max     min     min    )
  (simplify
-  (bit_and (op:cs @0 @1) (op:cs @0 @2))
+  (logic (op:cs @0 @1) (op:cs @0 @2))
   (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
        && TREE_CODE (@0) != INTEGER_CST)
    (op @0 (ext @1 @2)))))
 
 (simplify
  /* signbit(x) -> 0 if x is nonnegative.  */
  (SIGNBIT tree_expr_nonnegative_p@0)
  { integer_zero_node; })
 
 (simplify
Index: gcc/testsuite/gcc.dg/tree-ssa/minmax-loopend-2.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/minmax-loopend-2.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/tree-ssa/minmax-loopend-2.c	(working copy)
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int and_test(long a, long b, long c) {
+  int cmp1 = a > b;
+  int cmp2 = a > c;
+  return cmp1 & cmp2;
+}
+
+int ior_test (long a, long b, long c) {
+  int cmp1 = a < b;
+  int cmp2 = a < c;
+  return cmp1 | cmp2;
+}
+
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "optimized" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/minmax-loopend.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/minmax-loopend.c	(revision 259767)
+++ gcc/testsuite/gcc.dg/tree-ssa/minmax-loopend.c	(working copy)
@@ -1,17 +1,16 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -fdump-tree-optimized" } */
 
-int min_test(long a, long b, long c) {
+int and_test(long a, long b, long c) {
   int cmp1 = a < b;
   int cmp2 = a < c;
   return cmp1 & cmp2;
 }
 
-int max_test (long a, long b, long c) {
+int ior_test (long a, long b, long c) {
   int cmp1 = a > b;
   int cmp2 = a > c;
-  return cmp1 & cmp2;
+  return cmp1 | cmp2;
 }
 
-/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "MAX_EXPR" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "optimized" } } */

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