public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][middle-end/88784] Middle end is missing some optimizations about unsigned
@ 2019-06-27  6:12 Li Jia He
  2019-06-27 15:48 ` Jeff Law
  0 siblings, 1 reply; 56+ messages in thread
From: Li Jia He @ 2019-06-27  6:12 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, wschmidt, rguenther, Li Jia He

Hi,

According to the optimizable case described by Qi Feng on
issue 88784, we can combine the cases into the following:

1. x >  y  &&  x != XXX_MIN  -->   x > y
2. x >  y  &&  x == XXX_MIN  -->   false
3. x <= y  &&  x == XXX_MIN  -->   x == XXX_MIN

4. x <  y  &&  x != XXX_MAX  -->   x < y
5. x <  y  &&  x == XXX_MAX  -->   false
6. x >= y  &&  x == XXX_MAX  -->   x == XXX_MAX

7. x >  y  ||  x != XXX_MIN  -->   x != XXX_MIN
8. x <= y  ||  x != XXX_MIN  -->   true
9. x <= y  ||  x == XXX_MIN  -->   x <= y

10. x <  y  ||  x != XXX_MAX  -->   x != UXXX_MAX
11. x >= y  ||  x != XXX_MAX  -->   true
12. x >= y  ||  x == XXX_MAX  -->   x >= y

Note: XXX_MIN represents the minimum value of type x.
      XXX_MAX represents the maximum value of type x.

Here we don't need to care about whether the operation is
signed or unsigned.  For example, in the below equation:

'x >  y  &&  x != XXX_MIN  -->   x > y'

If the x type is signed int and XXX_MIN is INT_MIN, we can
optimize it to 'x > y'.  However, if the type of x is unsigned
int and XXX_MIN is 0, we can still optimize it to 'x > y'.

The regression testing for the patch was done on GCC mainline on

    powerpc64le-unknown-linux-gnu (Power 9 LE)

with no regressions.  Is it OK for trunk ?

Thanks,
Lijia He

gcc/ChangeLog

2019-06-27  Li Jia He  <helijia@linux.ibm.com>
	    Qi Feng  <ffengqi@linux.ibm.com>

	PR middle-end/88784
	* gimple-fold.c (and_comparisons_contain_equal_operands): New function.
	(and_comparisons_1): Use and_comparisons_contain_equal_operands.
	(or_comparisons_contain_equal_operands): New function.
	(or_comparisons_1): Use or_comparisons_contain_equal_operands.

gcc/testsuite/ChangeLog

2019-06-27  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.
---
 gcc/gimple-fold.c                 | 124 ++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/pr88784-1.c  |  30 ++++++++
 gcc/testsuite/gcc.dg/pr88784-10.c |  32 ++++++++
 gcc/testsuite/gcc.dg/pr88784-11.c |  30 ++++++++
 gcc/testsuite/gcc.dg/pr88784-12.c |  30 ++++++++
 gcc/testsuite/gcc.dg/pr88784-2.c  |  30 ++++++++
 gcc/testsuite/gcc.dg/pr88784-3.c  |  32 ++++++++
 gcc/testsuite/gcc.dg/pr88784-4.c  |  32 ++++++++
 gcc/testsuite/gcc.dg/pr88784-5.c  |  31 ++++++++
 gcc/testsuite/gcc.dg/pr88784-6.c  |  31 ++++++++
 gcc/testsuite/gcc.dg/pr88784-7.c  |  31 ++++++++
 gcc/testsuite/gcc.dg/pr88784-8.c  |  31 ++++++++
 gcc/testsuite/gcc.dg/pr88784-9.c  |  32 ++++++++
 13 files changed, 496 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-1.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-10.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-11.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-12.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-2.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-3.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-4.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-5.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-6.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-7.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-8.c
 create mode 100644 gcc/testsuite/gcc.dg/pr88784-9.c

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index dfb31a02078..6d2472d2fcb 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -5535,6 +5535,62 @@ and_var_with_comparison_1 (gimple *stmt,
   return NULL_TREE;
 }
 
+/* Try to simplify the AND of two comparisons defined by
+   (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
+   This optimization needs to satisfy op1a equal to op2a
+   or op1b equal to op2a.  If this can be done without
+   constructing an intermediate value, return the resulting
+   tree; otherwise NULL_TREE is returned.  */
+
+static tree
+and_comparisons_contain_equal_operands (enum tree_code code1, tree op1a,
+					tree op1b, enum tree_code code2,
+					tree op2a, tree op2b)
+{
+  /* Transform ((Y1 CODE1 X) AND (X CODE2 Y2)) to
+     ((X CODE1' Y1) AND (X CODE2 Y2)).  */
+  if (!operand_equal_p (op1a, op1b, 0) && operand_equal_p (op1b, op2a, 0)
+      && !operand_equal_p (op2a, op2b, 0))
+    return and_comparisons_contain_equal_operands (swap_tree_comparison (code1),
+						   op1b, op1a, code2, op2a,
+						   op2b);
+
+  tree op1a_type = TREE_TYPE (op1a);
+  tree op1b_type = TREE_TYPE (op1b);
+  tree op2b_type = TREE_TYPE (op2b);
+
+  if (INTEGRAL_TYPE_P (op1a_type) && INTEGRAL_TYPE_P (op1b_type)
+      && operand_equal_p (op1a, op2a, 0) && TREE_CODE (op2b) == INTEGER_CST)
+    {
+      if (wi::eq_p (wi::to_wide (op2b), wi::min_value (op2b_type)))
+	{
+	  /* x > y && x != XXX_MIN --> x > y  */
+	  if (code1 == GT_EXPR && code2 == NE_EXPR)
+	    return fold_build2 (code1, boolean_type_node, op1a, op1b);
+	  /* x > y && x == XXX_MIN --> false  */
+	  if (code1 == GT_EXPR && code2 == EQ_EXPR)
+	    return boolean_false_node;
+	  /* x <= y && x == XXX_MIN --> x == XXX_MIN  */
+	  if (code1 == LE_EXPR && code2 == EQ_EXPR)
+	    return fold_build2 (code2, boolean_type_node, op2a, op2b);
+	}
+      else if (wi::eq_p (wi::to_wide (op2b), wi::max_value (op2b_type)))
+	{
+	  /* x < y && x != XXX_MAX --> x < y  */
+	  if (code1 == LT_EXPR && code2 == NE_EXPR)
+	    return fold_build2 (code1, boolean_type_node, op1a, op1b);
+	  /* x < y && x == XXX_MAX --> false  */
+	  if (code1 == LT_EXPR && code2 == EQ_EXPR)
+	    return boolean_false_node;
+	  /* x >= y && x == XXX_MAX --> x == XXX_MAX  */
+	  if (code1 == GE_EXPR && code2 == EQ_EXPR)
+	    return fold_build2 (code2, boolean_type_node, op2a, op2b);
+	}
+    }
+
+  return NULL_TREE;
+}
+
 /* Try to simplify the AND of two comparisons defined by
    (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
    If this can be done without constructing an intermediate value,
@@ -5546,6 +5602,12 @@ static tree
 and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
 		   enum tree_code code2, tree op2a, tree op2b)
 {
+  /* Try to optimize ((x CODE1 y1) AND (x CODE2 y2))
+     and ((y1 CODE1 x) AND (x CODE2 y2)).  */
+  if (tree t = and_comparisons_contain_equal_operands (code1, op1a, op1b, code2,
+						       op2a, op2b))
+    return t;
+
   tree truth_type = truth_type_for (TREE_TYPE (op1a));
 
   /* First check for ((x CODE1 y) AND (x CODE2 y)).  */
@@ -5999,6 +6061,62 @@ or_var_with_comparison_1 (gimple *stmt,
   return NULL_TREE;
 }
 
+/* Try to simplify the OR of two comparisons defined by
+   (OP1A CODE1 OP1B) or (OP2A CODE2 OP2B), respectively.
+   This optimization needs to satisfy op1a equal to op2a
+   or op1b equal to op2a.  If this can be done without
+   constructing an intermediate value, return the resulting
+   tree; otherwise NULL_TREE is returned.  */
+
+static tree
+or_comparisons_contain_equal_operands (enum tree_code code1, tree op1a,
+				       tree op1b, enum tree_code code2,
+				       tree op2a, tree op2b)
+{
+  /* Transform ((Y1 CODE1 X) OR (X CODE2 Y2)) to
+     ((X CODE1' Y1) OR (X CODE2 Y2)).  */
+  if (!operand_equal_p (op1a, op1b, 0) && operand_equal_p (op1b, op2a, 0)
+      && !operand_equal_p (op2a, op2b, 0))
+    return or_comparisons_contain_equal_operands (swap_tree_comparison (code1),
+						  op1b, op1a, code2, op2a,
+						  op2b);
+
+  tree op1a_type = TREE_TYPE (op1a);
+  tree op1b_type = TREE_TYPE (op1b);
+  tree op2b_type = TREE_TYPE (op2b);
+
+  if (INTEGRAL_TYPE_P (op1a_type) && INTEGRAL_TYPE_P (op1b_type)
+      && operand_equal_p (op1a, op2a, 0) && TREE_CODE (op2b) == INTEGER_CST)
+    {
+      if (wi::eq_p (wi::to_wide (op2b), wi::min_value (op2b_type)))
+	{
+	  /* x > y || x != XXX_MIN --> x != XXX_MIN  */
+	  if (code1 == GT_EXPR && code2 == NE_EXPR)
+	    return fold_build2 (code2, boolean_type_node, op2a, op2b);
+	  /* x <= y || x != XXX_MIN --> true  */
+	  if (code1 == LE_EXPR && code2 == NE_EXPR)
+	    return boolean_true_node;
+	  /* x <= y || x == XXX_MIN --> x <= y  */
+	  if (code1 == LE_EXPR && code2 == EQ_EXPR)
+	    return fold_build2 (code1, boolean_type_node, op1a, op1b);
+	}
+      else if (wi::eq_p (wi::to_wide (op2b), wi::max_value (op2b_type)))
+	{
+	  /* x < y || x != XXX_MAX --> x != XXX_MAX  */
+	  if (code1 == LT_EXPR && code2 == NE_EXPR)
+	    return fold_build2 (code2, boolean_type_node, op2a, op2b);
+	  /* x >= y || x != XXX_MAX --> true  */
+	  if (code1 == GE_EXPR && code2 == NE_EXPR)
+	    return boolean_true_node;
+	  /* x >= y || x == XXX_MAX --> x >= y  */
+	  if (code1 == GE_EXPR && code2 == EQ_EXPR)
+	    return fold_build2 (code1, boolean_type_node, op1a, op1b);
+	}
+    }
+
+  return NULL_TREE;
+}
+
 /* Try to simplify the OR of two comparisons defined by
    (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
    If this can be done without constructing an intermediate value,
@@ -6010,6 +6128,12 @@ static tree
 or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
 		  enum tree_code code2, tree op2a, tree op2b)
 {
+  /* Try to optimize ((x CODE1 y1) OR (x CODE2 y2))
+     and ((y1 CODE1 x) OR (x CODE2 y2)).  */
+  if (tree t = or_comparisons_contain_equal_operands (code1, op1a, op1b, code2,
+						      op2a, op2b))
+    return t;
+
   tree truth_type = truth_type_for (TREE_TYPE (op1a));
 
   /* First check for ((x CODE1 y) OR (x CODE2 y)).  */
diff --git a/gcc/testsuite/gcc.dg/pr88784-1.c b/gcc/testsuite/gcc.dg/pr88784-1.c
new file mode 100644
index 00000000000..067d40d0739
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcombine --param logical-op-non-short-circuit=0" } */
+
+#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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-10.c b/gcc/testsuite/gcc.dg/pr88784-10.c
new file mode 100644
index 00000000000..fa185d680c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-10.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dce3 --param logical-op-non-short-circuit=1" } */
+
+#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 " != " "dce3" } } */
+/* { dg-final { scan-tree-dump-not " <= " "dce3" } } */
+/* { dg-final { scan-tree-dump-not " >= " "dce3" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-11.c b/gcc/testsuite/gcc.dg/pr88784-11.c
new file mode 100644
index 00000000000..4465910efbb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-11.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcombine --param logical-op-non-short-circuit=0" } */
+
+#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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-12.c b/gcc/testsuite/gcc.dg/pr88784-12.c
new file mode 100644
index 00000000000..477bba07821
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-12.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dce3 --param logical-op-non-short-circuit=1" } */
+
+#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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-2.c b/gcc/testsuite/gcc.dg/pr88784-2.c
new file mode 100644
index 00000000000..265ddc7ceeb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-2.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dce3 --param logical-op-non-short-circuit=1" } */
+
+#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 " != " "dce3" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-3.c b/gcc/testsuite/gcc.dg/pr88784-3.c
new file mode 100644
index 00000000000..be2ce315e60
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-3.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcombine --param logical-op-non-short-circuit=0" } */
+
+#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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-4.c b/gcc/testsuite/gcc.dg/pr88784-4.c
new file mode 100644
index 00000000000..b927e712464
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-4.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dce3 --param logical-op-non-short-circuit=1" } */
+
+#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 " == " "dce3" } } */
+/* { dg-final { scan-tree-dump-not " > " "dce3" } } */
+/* { dg-final { scan-tree-dump-not " < " "dce3" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-5.c b/gcc/testsuite/gcc.dg/pr88784-5.c
new file mode 100644
index 00000000000..c6a349d7c75
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-5.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcombine --param logical-op-non-short-circuit=0" } */
+
+#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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-6.c b/gcc/testsuite/gcc.dg/pr88784-6.c
new file mode 100644
index 00000000000..5b5d2221bf0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-6.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dce3 --param logical-op-non-short-circuit=1" } */
+
+#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 " <= " "dce3" } } */
+/* { dg-final { scan-tree-dump-not " >= " "dce3" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-7.c b/gcc/testsuite/gcc.dg/pr88784-7.c
new file mode 100644
index 00000000000..937d2d26593
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-7.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcombine --param logical-op-non-short-circuit=0" } */
+
+#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" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-8.c b/gcc/testsuite/gcc.dg/pr88784-8.c
new file mode 100644
index 00000000000..7f5c845eb27
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-8.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dce3 --param logical-op-non-short-circuit=1" } */
+
+#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 " > " "dce3" } } */
+/* { dg-final { scan-tree-dump-not " < " "dce3" } } */
diff --git a/gcc/testsuite/gcc.dg/pr88784-9.c b/gcc/testsuite/gcc.dg/pr88784-9.c
new file mode 100644
index 00000000000..94f62d94ede
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88784-9.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ifcombine --param logical-op-non-short-circuit=0" } */
+
+#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" } } */
-- 
2.17.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

end of thread, other threads:[~2019-09-16 14:23 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-27  6:12 [PATCH][middle-end/88784] Middle end is missing some optimizations about unsigned Li Jia He
2019-06-27 15:48 ` Jeff Law
2019-06-28  4:55   ` Li Jia He
2019-06-28 17:02     ` Andrew Pinski
2019-07-01  7:31       ` Richard Biener
2019-07-02  7:41         ` Li Jia He
2019-07-02  8:09           ` Richard Biener
2019-07-02  8:51             ` Richard Biener
2019-07-16  6:54               ` Li Jia He
2019-08-30 11:16                 ` Martin Liška
2019-09-05 13:01                 ` Richard Biener
2019-09-05 18:47                   ` Martin Liška
2019-09-06  8:01                     ` Richard Biener
2019-09-06  8:04                       ` Martin Liška
2019-09-06 10:13                   ` [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd Martin Liška
2019-09-09 12:23                     ` Martin Liška
2019-09-09 13:10                       ` Marc Glisse
2019-09-09 13:30                         ` Martin Liška
2019-09-09 13:39                           ` Richard Biener
2019-09-09 13:10                       ` Richard Biener
2019-09-09 13:40                         ` Martin Liška
2019-09-09 13:42                           ` Richard Biener
2019-09-09 13:45                             ` Martin Liška
2019-09-09 13:55                               ` Richard Biener
2019-09-10  7:40                                 ` Martin Liška
     [not found]                                   ` <ba4ec7b3-0d0d-ca7b-b2d9-2f34478a23f4@linux.ibm.com>
2019-09-11  8:51                                     ` Martin Liška
2019-09-11 11:16                                   ` Martin Liška
2019-09-11 12:23                                     ` Richard Biener
2019-09-11 13:55                                       ` Martin Liška
2019-09-09 12:24                     ` [PATCH 4/5] Rewrite first part of or_comparisons_1 into match.pd Martin Liška
2019-09-11 11:19                       ` Martin Liška
2019-09-11 13:57                         ` Martin Liška
2019-09-16  9:05                           ` Richard Biener
2019-09-09 12:24                     ` [PATCH 3/5] Rewrite part of and_comparisons_1 " Martin Liška
2019-09-09 13:41                       ` Martin Liška
2019-09-10  7:41                         ` Martin Liška
2019-09-10 11:19                           ` Marc Glisse
2019-09-11  8:27                             ` Martin Liška
2019-09-11 11:18                               ` Martin Liška
2019-09-11 12:44                                 ` Richard Biener
2019-09-11 13:19                                   ` Martin Liška
2019-09-11 13:57                                     ` Martin Liška
2019-09-16  9:04                                       ` Richard Biener
2019-09-16 13:47                                         ` Martin Liška
2019-09-10  8:52                         ` Bernhard Reutner-Fischer
2019-09-11  8:11                           ` Martin Liška
2019-09-09 12:25                     ` [PATCH 5/5] Rewrite second part of or_comparisons_1 " Martin Liška
2019-09-11 11:19                       ` Martin Liška
2019-09-11 13:57                         ` Martin Liška
2019-09-16  9:07                           ` Richard Biener
2019-09-16 14:23                             ` Martin Liška
2019-09-05 13:17                 ` [PATCH][middle-end/88784] Middle end is missing some optimizations about unsigned Richard Biener
2019-09-05 18:47                   ` Martin Liška
2019-09-06 10:14                   ` [PATCH 2/2] Fix PR88784, middle " Martin Liška
2019-09-11 13:08                     ` Richard Biener
2019-09-11 13:56                       ` Martin Liška

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).