+2019-09-16 Li Jia He <helijia@linux.ibm.com>
+ Qi Feng <ffengqi@linux.ibm.com>
+
+ PR middle-end/88784
+ * match.pd (x > y && x != XXX_MIN): Optimize into 'x > y'.
+ (x > y && x == XXX_MIN): Optimize into 'false'.
+ (x <= y && x == XXX_MIN): Optimize into 'x == XXX_MIN'.
+ (x < y && x != XXX_MAX): Optimize into 'x < y'.
+ (x < y && x == XXX_MAX): Optimize into 'false'.
+ (x >= y && x == XXX_MAX): Optimize into 'x == XXX_MAX'.
+ (x > y || x != XXX_MIN): Optimize into 'x != XXX_MIN'.
+ (x <= y || x != XXX_MIN): Optimize into 'true'.
+ (x <= y || x == XXX_MIN): Optimize into 'x <= y'.
+ (x < y || x != XXX_MAX): Optimize into 'x != XXX_MAX'.
+ (x >= y || x != XXX_MAX): Optimize into 'true'.
+ (x >= y || x == XXX_MAX): Optimize into 'x >= y'.
+
2019-09-16 Li Jia He <helijia@linux.ibm.com>
Martin Liska <mliska@suse.cz>
{ wide_int_to_tree (type, (wi::to_wide (@1)
& (bitpos / BITS_PER_UNIT))); }))))
+(match min_value
+ INTEGER_CST
+ (if (INTEGRAL_TYPE_P (type)
+ && wi::eq_p (wi::to_wide (t), wi::min_value (type)))))
+
+(match max_value
+ INTEGER_CST
+ (if (INTEGRAL_TYPE_P (type)
+ && wi::eq_p (wi::to_wide (t), wi::max_value (type)))))
+
+/* x > y && x != XXX_MIN --> x > y
+ x > y && x == XXX_MIN --> false . */
+(for eqne (eq ne)
+ (simplify
+ (bit_and:c (gt:c@2 @0 @1) (eqne @0 min_value))
+ (switch
+ (if (eqne == EQ_EXPR)
+ { constant_boolean_node (false, type); })
+ (if (eqne == NE_EXPR)
+ @2)
+ )))
+
+/* x < y && x != XXX_MAX --> x < y
+ x < y && x == XXX_MAX --> false. */
+(for eqne (eq ne)
+ (simplify
+ (bit_and:c (lt:c@2 @0 @1) (eqne @0 max_value))
+ (switch
+ (if (eqne == EQ_EXPR)
+ { constant_boolean_node (false, type); })
+ (if (eqne == NE_EXPR)
+ @2)
+ )))
+
+/* x <= y && x == XXX_MIN --> x == XXX_MIN. */
+(simplify
+ (bit_and:c (le:c @0 @1) (eq@2 @0 min_value))
+ @2)
+
+/* x >= y && x == XXX_MAX --> x == XXX_MAX. */
+(simplify
+ (bit_and:c (ge:c @0 @1) (eq@2 @0 max_value))
+ @2)
+
+/* x > y || x != XXX_MIN --> x != XXX_MIN. */
+(simplify
+ (bit_ior:c (gt:c @0 @1) (ne@2 @0 min_value))
+ @2)
+
+/* x <= y || x != XXX_MIN --> true. */
+(simplify
+ (bit_ior:c (le:c @0 @1) (ne @0 min_value))
+ { constant_boolean_node (true, type); })
+
+/* x <= y || x == XXX_MIN --> x <= y. */
+(simplify
+ (bit_ior:c (le:c@2 @0 @1) (eq @0 min_value))
+ @2)
+
+/* x < y || x != XXX_MAX --> x != XXX_MAX. */
+(simplify
+ (bit_ior:c (lt:c @0 @1) (ne@2 @0 max_value))
+ @2)
+
+/* x >= y || x != XXX_MAX --> true
+ x >= y || x == XXX_MAX --> x >= y. */
+(for eqne (eq ne)
+ (simplify
+ (bit_ior:c (ge:c@2 @0 @1) (eqne @0 max_value))
+ (switch
+ (if (eqne == EQ_EXPR)
+ @2)
+ (if (eqne == NE_EXPR)
+ { constant_boolean_node (true, type); }))))
/* We can't reassociate at all for saturating types. */
(if (!TYPE_SATURATING (type))
on c, so could drop potentially-trapping arithmetic, but that's a valid
simplification if the result of the operation isn't needed.
- Avoid speculatively generating a stand-alone vector comparison
- on targets that might not support them. Any target implementing
- conditional internal functions must support the same comparisons
- inside and outside a VEC_COND_EXPR. */
+ Avoid speculatively generating a stand-alone vector comparison
+ on targets that might not support them. Any target implementing
+ conditional internal functions must support the same comparisons
+ inside and outside a VEC_COND_EXPR. */
#if GIMPLE
(for uncond_op (UNCOND_BINARY)
+2019-09-16 Li Jia He <helijia@linux.ibm.com>
+ Qi Feng <ffengqi@linux.ibm.com>
+
+ PR middle-end/88784
+ * gcc.dg/pr88784-1.c: New testcase.
+ * gcc.dg/pr88784-2.c: New testcase.
+ * gcc.dg/pr88784-3.c: New testcase.
+ * gcc.dg/pr88784-4.c: New testcase.
+ * gcc.dg/pr88784-5.c: New testcase.
+ * gcc.dg/pr88784-6.c: New testcase.
+ * gcc.dg/pr88784-7.c: New testcase.
+ * gcc.dg/pr88784-8.c: New testcase.
+ * gcc.dg/pr88784-9.c: New testcase.
+ * gcc.dg/pr88784-10.c: New testcase.
+ * gcc.dg/pr88784-11.c: New testcase.
+ * gcc.dg/pr88784-12.c: New testcase.
+
2019-09-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/91756
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcombine" } */
+
+#include <limits.h>
+
+_Bool and1(unsigned x, unsigned y)
+{
+ /* x > y && x != 0 --> x > y */
+ return x > y && x != 0;
+}
+
+_Bool and2(unsigned x, unsigned y)
+{
+ /* x < y && x != UINT_MAX --> x < y */
+ return x < y && x != UINT_MAX;
+}
+
+_Bool and3(signed x, signed y)
+{
+ /* x > y && x != INT_MIN --> x > y */
+ return x > y && x != INT_MIN;
+}
+
+_Bool and4(signed x, signed y)
+{
+ /* x < y && x != INT_MAX --> x < y */
+ return x < y && x != INT_MAX;
+}
+
+/* { dg-final { scan-tree-dump-not " != " "ifcombine" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include <limits.h>
+
+_Bool or1(unsigned x, unsigned y)
+{
+ /* x <= y || x != 0 --> true */
+ return x <= y || x != 0;
+}
+
+_Bool or2(unsigned x, unsigned y)
+{
+ /* x >= y || x != UINT_MAX --> true */
+ return x >= y || x != UINT_MAX;
+}
+
+_Bool or3(signed x, signed y)
+{
+ /* x <= y || x != INT_MIN --> true */
+ return x <= y || x != INT_MIN;
+}
+
+_Bool or4(signed x, signed y)
+{
+ /* x >= y || x != INT_MAX --> true */
+ return x >= y || x != INT_MAX;
+}
+
+/* { dg-final { scan-tree-dump-not " != " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " <= " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " >= " "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcombine" } */
+
+#include <limits.h>
+
+_Bool or1(unsigned x, unsigned y)
+{
+ /* x <= y || x == 0 --> x <= y */
+ return x <= y || x == 0;
+}
+
+_Bool or2(unsigned x, unsigned y)
+{
+ /* x >= y || x == UINT_MAX --> x >= y */
+ return x >= y || x == UINT_MAX;
+}
+
+_Bool or3(signed x, signed y)
+{
+ /* x <= y || x == INT_MIN --> x <= y */
+ return x <= y || x == INT_MIN;
+}
+
+_Bool or4(signed x, signed y)
+{
+ /* x >= y || x == INT_MAX --> x >= y */
+ return x >= y || x == INT_MAX;
+}
+
+/* { dg-final { scan-tree-dump-not " == " "ifcombine" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dce3" } */
+
+#include <limits.h>
+
+_Bool or1(unsigned x, unsigned y)
+{
+ /* x <= y || x == 0 --> x <= y */
+ return x <= y || x == 0;
+}
+
+_Bool or2(unsigned x, unsigned y)
+{
+ /* x >= y || x == UINT_MAX --> x >= y */
+ return x >= y || x == UINT_MAX;
+}
+
+_Bool or3(signed x, signed y)
+{
+ /* x <= y || x == INT_MIN --> x <= y */
+ return x <= y || x == INT_MIN;
+}
+
+_Bool or4(signed x, signed y)
+{
+ /* x >= y || x == INT_MAX --> x >= y */
+ return x >= y || x == INT_MAX;
+}
+
+/* { dg-final { scan-tree-dump-not " == " "dce3" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include <limits.h>
+
+_Bool and1(unsigned x, unsigned y)
+{
+ /* x > y && x != 0 --> x > y */
+ return x > y && x != 0;
+}
+
+_Bool and2(unsigned x, unsigned y)
+{
+ /* x < y && x != UINT_MAX --> x < y */
+ return x < y && x != UINT_MAX;
+}
+
+_Bool and3(signed x, signed y)
+{
+ /* x > y && x != INT_MIN --> x > y */
+ return x > y && x != INT_MIN;
+}
+
+_Bool and4(signed x, signed y)
+{
+ /* x < y && x != INT_MAX --> x < y */
+ return x < y && x != INT_MAX;
+}
+
+/* { dg-final { scan-tree-dump-not " != " "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcombine" } */
+
+#include <limits.h>
+
+_Bool and1(unsigned x, unsigned y)
+{
+ /* x > y && x == 0 --> false */
+ return x > y && x == 0;
+}
+
+_Bool and2(unsigned x, unsigned y)
+{
+ /* x < y && x == UINT_MAX --> false */
+ return x < y && x == UINT_MAX;
+}
+
+_Bool and3(signed x, signed y)
+{
+ /* x > y && x == INT_MIN --> false */
+ return x > y && x == INT_MIN;
+}
+
+_Bool and4(signed x, signed y)
+{
+ /* x < y && x == INT_MAX --> false */
+ return x < y && x == INT_MAX;
+}
+
+/* { dg-final { scan-tree-dump-not " == " "ifcombine" } } */
+/* { dg-final { scan-tree-dump-not " > " "ifcombine" } } */
+/* { dg-final { scan-tree-dump-not " < " "ifcombine" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include <limits.h>
+
+_Bool and1(unsigned x, unsigned y)
+{
+ /* x > y && x == 0 --> false */
+ return x > y && x == 0;
+}
+
+_Bool and2(unsigned x, unsigned y)
+{
+ /* x < y && x == UINT_MAX --> false */
+ return x < y && x == UINT_MAX;
+}
+
+_Bool and3(signed x, signed y)
+{
+ /* x > y && x == INT_MIN --> false */
+ return x > y && x == INT_MIN;
+}
+
+_Bool and4(signed x, signed y)
+{
+ /* x < y && x == INT_MAX --> false */
+ return x < y && x == INT_MAX;
+}
+
+/* { dg-final { scan-tree-dump-not " == " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " > " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " < " "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcombine" } */
+
+#include <limits.h>
+
+_Bool and1(unsigned x, unsigned y)
+{
+ /* x <= y && x == 0 --> x == 0 */
+ return x <= y && x == 0;
+}
+
+_Bool and2(unsigned x, unsigned y)
+{
+ /* x >= y && x == UINT_MAX --> x == UINT_MAX */
+ return x >= y && x == UINT_MAX;
+}
+
+_Bool and3(signed x, signed y)
+{
+ /* x <= y && x == INT_MIN --> x == INT_MIN */
+ return x <= y && x == INT_MIN;
+}
+
+_Bool and4(signed x, signed y)
+{
+ /* x >= y && x == INT_MAX --> x == INT_MAX */
+ return x >= y && x == INT_MAX;
+}
+
+/* { dg-final { scan-tree-dump-not " <= " "ifcombine" } } */
+/* { dg-final { scan-tree-dump-not " >= " "ifcombine" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include <limits.h>
+
+_Bool and1(unsigned x, unsigned y)
+{
+ /* x <= y && x == 0 --> x == 0 */
+ return x <= y && x == 0;
+}
+
+_Bool and2(unsigned x, unsigned y)
+{
+ /* x >= y && x == UINT_MAX --> x == UINT_MAX */
+ return x >= y && x == UINT_MAX;
+}
+
+_Bool and3(signed x, signed y)
+{
+ /* x <= y && x == INT_MIN --> x == INT_MIN */
+ return x <= y && x == INT_MIN;
+}
+
+_Bool and4(signed x, signed y)
+{
+ /* x >= y && x == INT_MAX --> x == INT_MAX */
+ return x >= y && x == INT_MAX;
+}
+
+/* { dg-final { scan-tree-dump-not " <= " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " >= " "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcombine" } */
+
+#include <limits.h>
+
+_Bool or1(unsigned x, unsigned y)
+{
+ /* x > y || x != 0 --> x != 0 */
+ return x > y || x != 0;
+}
+
+_Bool or2(unsigned x, unsigned y)
+{
+ /* x < y || x != UINT_MAX --> x != UINT_MAX */
+ return x < y || x != UINT_MAX;
+}
+
+_Bool or3(signed x, signed y)
+{
+ /* x > y || x != INT_MIN --> x != INT_MIN */
+ return x > y || x != INT_MIN;
+}
+
+_Bool or4(signed x, signed y)
+{
+ /* x < y || x != INT_MAX --> x != INT_MAX */
+ return x < y || x != INT_MAX;
+}
+
+/* { dg-final { scan-tree-dump-not " > " "ifcombine" } } */
+/* { dg-final { scan-tree-dump-not " < " "ifcombine" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include <limits.h>
+
+_Bool or1(unsigned x, unsigned y)
+{
+ /* x > y || x != 0 --> x != 0 */
+ return x > y || x != 0;
+}
+
+_Bool or2(unsigned x, unsigned y)
+{
+ /* x < y || x != UINT_MAX --> x != UINT_MAX */
+ return x < y || x != UINT_MAX;
+}
+
+_Bool or3(signed x, signed y)
+{
+ /* x > y || x != INT_MIN --> x != INT_MIN */
+ return x > y || x != INT_MIN;
+}
+
+_Bool or4(signed x, signed y)
+{
+ /* x < y || x != INT_MAX --> x != INT_MAX */
+ return x < y || x != INT_MAX;
+}
+
+/* { dg-final { scan-tree-dump-not " > " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " < " "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcombine" } */
+
+#include <limits.h>
+
+_Bool or1(unsigned x, unsigned y)
+{
+ /* x <= y || x != 0 --> true */
+ return x <= y || x != 0;
+}
+
+_Bool or2(unsigned x, unsigned y)
+{
+ /* x >= y || x != UINT_MAX --> true */
+ return x >= y || x != UINT_MAX;
+}
+
+_Bool or3(signed x, signed y)
+{
+ /* x <= y || x != INT_MIN --> true */
+ return x <= y || x != INT_MIN;
+}
+
+_Bool or4(signed x, signed y)
+{
+ /* x >= y || x != INT_MAX --> true */
+ return x >= y || x != INT_MAX;
+}
+
+/* { dg-final { scan-tree-dump-not " != " "ifcombine" } } */
+/* { dg-final { scan-tree-dump-not " <= " "ifcombine" } } */
+/* { dg-final { scan-tree-dump-not " >= " "ifcombine" } } */