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]

[patch tree-optimization]: Fix for PR 45397 part 2 of 2


Hi,

this is the second part of the patch for this problem.  It adds some
basic simplifications for ==/!=
comparisons for eliminating redudant operands.

It adds the following patterns:
  -X ==/!= Z - X -> Z ==/!= 0.
  ~X ==/!= Z ^ X -> Z ==/!= ~0
  X ==/!= X - Y -> Y == 0
  X ==/!= X + Y -> Y == 0
  X ==/!= X ^ Y -> Y == 0
  (X - Y) ==/!= (Z - Y) -> X ==/!= Z
  (Y - X) ==/!= (Y - Z) -> X ==/!= Z
  (X + Y) ==/!= (X + Z) -> Y ==/!= Z
  (X + Y) ==/!= (Z + X) -> Y ==/!= Z
  (X ^ Y) ==/!= (Z ^ X) -> Y ==/!= Z

ChangeLog

2012-03-15  Kai Tietz  <ktietz@redhat.com>

	PR tree-optimization/45397
	* tree-ssa-forwprop.c (compare_equal_optimized_1): Add
	simplification patterns for ==/!= comparison.

2012-03-15  Kai Tietz  <ktietz@redhat.com>

	* gcc.dg/tree-ssa/pr45397-2.c: New test.

Regression tested for all languages (including Ada and Obj-C) on
x86_64-unknown-linux-gnu.  Ok for apply?

Regards,
Kai

Index: gcc-trunk/gcc/tree-ssa-forwprop.c
===================================================================
--- gcc-trunk.orig/gcc/tree-ssa-forwprop.c
+++ gcc-trunk/gcc/tree-ssa-forwprop.c
@@ -381,6 +381,99 @@ compare_equal_optimize_1 (gimple stmt, e
       || !INTEGRAL_TYPE_P (type_outer))
     return NULL_TREE;

+  /* Simplify -X ==/!= Z - X -> Z ==/!= 0.  */
+  if (TREE_CODE (op0) == NEGATE_EXPR
+      && !TREE_SIDE_EFFECTS (TREE_OPERAND (op0, 0))
+      && TREE_CODE (op1) == MINUS_EXPR
+      && TREE_OPERAND (op0, 0) == TREE_OPERAND (op1, 1))
+	return fold_build2_loc (gimple_location (stmt), code, type,
+	       			TREE_OPERAND (op1, 0),
+        			build_zero_cst (TREE_TYPE (op1)));
+
+  /* Simplify X - Z ==/!= -X -> Z ==/!= 0.  */
+  if (TREE_CODE (op1) == NEGATE_EXPR
+      && !TREE_SIDE_EFFECTS (TREE_OPERAND (op1, 0))
+      && TREE_CODE (op0) == MINUS_EXPR
+      && TREE_OPERAND (op1, 0) == TREE_OPERAND (op0, 1))
+	return fold_build2_loc (gimple_location (stmt), code, type,
+	       			TREE_OPERAND (op0, 0),
+        			build_zero_cst (TREE_TYPE (op0)));
+
+  /* Simplify ~X ==/!= X ^ Y to Y ==/!= ~0.  */
+  if (TREE_CODE (op0) == BIT_NOT_EXPR
+      && !TREE_SIDE_EFFECTS (TREE_OPERAND (op0, 0))
+      && TREE_CODE (op1) == BIT_XOR_EXPR)
+    {
+      if (TREE_OPERAND (op0, 0) == TREE_OPERAND (op1, 1))
+	return fold_build2_loc (gimple_location (stmt), code, type,
+	       			TREE_OPERAND (op1, 0),
+        			fold_build1 (BIT_NOT_EXPR,
+					     TREE_TYPE (op1),
+					     build_zero_cst (TREE_TYPE (op1))));
+      if (TREE_OPERAND (op0, 0) == TREE_OPERAND (op1, 0))
+	return fold_build2_loc (gimple_location (stmt), code, type,
+	       			TREE_OPERAND (op1, 1),
+        			fold_build1 (BIT_NOT_EXPR,
+					     TREE_TYPE (op1),
+					     build_zero_cst (TREE_TYPE (op1))));
+    }
+
+  /* Simplify X ^ Y ==/!= ~X to Y ==/!= ~0.  */
+  if (TREE_CODE (op1) == BIT_NOT_EXPR
+      && !TREE_SIDE_EFFECTS (TREE_OPERAND (op1, 0))
+      && TREE_CODE (op0) == BIT_XOR_EXPR)
+    {
+      if (TREE_OPERAND (op1, 0) == TREE_OPERAND (op0, 1))
+	return fold_build2_loc (gimple_location (stmt), code, type,
+	       			TREE_OPERAND (op0, 0),
+        			fold_build1 (BIT_NOT_EXPR,
+					     TREE_TYPE (op0),
+					     build_zero_cst (TREE_TYPE (op0))));
+      if (TREE_OPERAND (op1, 0) == TREE_OPERAND (op0, 0))
+	return fold_build2_loc (gimple_location (stmt), code, type,
+	       			TREE_OPERAND (op0, 1),
+        			fold_build1 (BIT_NOT_EXPR,
+					     TREE_TYPE (op0),
+					     build_zero_cst (TREE_TYPE (op0))));
+    }
+
+  /* For code being +, -, or ^-expression simplify (X code Y) ==/!= (Z code Y)
+     to (X ==/!= Z), and (X code Y) ==/!= (X code Z) to (Y ==/!= Z).  */
+  if (TREE_CODE (op0) == TREE_CODE (op1)
+      && (TREE_CODE (op0) == PLUS_EXPR
+          || TREE_CODE (op0) == MINUS_EXPR
+          || TREE_CODE (op0) == BIT_XOR_EXPR))
+    {
+      /* Simplify (X code Y) ==/!= (X code Z) to Y ==/!= Z.  */
+      if (TREE_OPERAND (op0, 0) == TREE_OPERAND (op1, 0)
+          && !TREE_SIDE_EFFECTS (TREE_OPERAND (op0, 0)))
+	return fold_build2_loc (gimple_location (stmt), code, type,
+	       			TREE_OPERAND (op0, 1),
+        			TREE_OPERAND (op1, 1));
+      /* Simplify (X code Y) ==/!= (Z code X) to Y ==/!= Z, if code isn't
+	 minus operation.  */
+      if (TREE_CODE (op0) != MINUS_EXPR
+          && TREE_OPERAND (op0, 0) == TREE_OPERAND (op1, 1)
+          && !TREE_SIDE_EFFECTS (TREE_OPERAND (op0, 0)))
+        return fold_build2_loc (gimple_location (stmt), code, type,
+        			TREE_OPERAND (op0, 1),
+        			TREE_OPERAND (op1, 0));
+      /* Simplify (Y code X) ==/!= (X code Z) to Y ==/!= Z, if code isn't
+	 minus operation.  */
+      if (TREE_CODE (op0) != MINUS_EXPR
+          && TREE_OPERAND (op0, 1) == TREE_OPERAND (op1, 0)
+          && !TREE_SIDE_EFFECTS (TREE_OPERAND (op0, 1)))
+        return fold_build2_loc (gimple_location (stmt), code, type,
+        			TREE_OPERAND (op0, 0),
+        			TREE_OPERAND (op1, 1));
+      /* Simplify (Y code X) ==/!= (Z code X) to Y ==/!= Z.  */
+      if (TREE_OPERAND (op0, 1) == TREE_OPERAND (op1, 1)
+          && !TREE_SIDE_EFFECTS (TREE_OPERAND (op0, 1)))
+        return fold_build2_loc (gimple_location (stmt), code, type,
+        			TREE_OPERAND (op0, 0),
+        			TREE_OPERAND (op1, 0));
+    }
+
   /* If OP0 isn't a conversion, then check if OP1 might be one.  If so
      swap arguments, otherwise return NULL_TREE.  */
   if (!CONVERT_EXPR_P (op0))
Index: gcc-trunk/gcc/testsuite/gcc.dg/tree-ssa/pr45397-2.c
===================================================================
--- /dev/null
+++ gcc-trunk/gcc/testsuite/gcc.dg/tree-ssa/pr45397-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int
+foo (const unsigned char *a, int b, int c)
+{
+  int x = (unsigned char) (a[b] + c);
+  int y = a[b] + c;
+  int z = (unsigned char) y;
+  return x == z;
+}
+
+/* { dg-final { scan-tree-dump-times "return 1" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+


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