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.gli...@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" } } */