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] Add X != !X pattern


This adds a pattern matching x != ~x on GIMPLE and allows CCP to
properly optimize the added testcase.  gimple_simplify gets confused
by the existing ~x == 1 -> x == 0 pattern which 
gimple_fold_stmt_to_constant_1 cannot reduce to a single value.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2015-08-04  Richard Biener  <rguenther@suse.de>

	* gimple-fold.c (gimple_fold_stmt_to_constant_1): Canonicalize
	bool compares on RHS.
	* match.pd: Add X ==/!= !X is false/true pattern.

	* gcc.dg/tree-ssa/ssa-ccp-38.c: New testcase.

Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c	(revision 226559)
+++ gcc/gimple-fold.c	(working copy)
@@ -5012,10 +5012,8 @@ gimple_fold_stmt_to_constant_1 (gimple s
 	       further propagation.  */
 	    if (subcode == POINTER_PLUS_EXPR)
 	      {
-		/* Handle binary operators that can appear in GIMPLE form.  */
 		tree op0 = (*valueize) (gimple_assign_rhs1 (stmt));
 		tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
-
 		if (TREE_CODE (op0) == ADDR_EXPR
 		    && TREE_CODE (op1) == INTEGER_CST)
 		  {
@@ -5027,6 +5025,38 @@ gimple_fold_stmt_to_constant_1 (gimple s
 				      unshare_expr (op0), off));
 		  }
 	      }
+	    /* Canonicalize bool != 0 and bool == 0 appearing after
+	       valueization.  While gimple_simplify handles this
+	       it can get confused by the ~X == 1 -> X == 0 transform
+	       which we cant reduce to a SSA name or a constant
+	       (and we have no way to tell gimple_simplify to not
+	       consider those transforms in the first place).  */
+	    else if (subcode == EQ_EXPR
+		     || subcode == NE_EXPR)
+	      {
+		tree lhs = gimple_assign_lhs (stmt);
+		tree op0 = gimple_assign_rhs1 (stmt);
+		if (useless_type_conversion_p (TREE_TYPE (lhs),
+					       TREE_TYPE (op0)))
+		  {
+		    tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
+		    op0 = (*valueize) (op0);
+		    if (subcode == NE_EXPR)
+		      {
+			if (integer_zerop (op1))
+			  return op0;
+			else if (integer_zerop (op0))
+			  return op1;
+		      }
+		    else
+		      {
+			if (integer_onep (op1))
+			  return op0;
+			else if (integer_onep (op0))
+			  return op1;
+		      }
+		  }
+	      }
 	    return NULL_TREE;
 
           case GIMPLE_TERNARY_RHS:
Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 226559)
+++ gcc/match.pd	(working copy)
@@ -618,6 +618,11 @@ (define_operator_list CBRT BUILT_IN_CBRT
  (simplify
   (op:c truth_valued_p@0 (logical_inverted_value @0))
   { constant_boolean_node (true, type); }))
+/* X ==/!= !X is false/true.  */
+(for op (eq ne)
+ (simplify
+  (op:c truth_valued_p@0 (logical_inverted_value @0))
+  { constant_boolean_node (op == NE_EXPR ? true : false, type); }))
 
 /* If arg1 and arg2 are booleans (or any single bit type)
    then try to simplify:
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-38.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-38.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-38.c	(working copy)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ccp1" } */
+
+int foo (_Bool x)
+{
+  _Bool t = 1;
+  _Bool xx = !x;
+  _Bool y = xx == t;
+  _Bool z = y == x;
+  return z ? 1 : 0;
+}
+
+/* { dg-final { scan-tree-dump "return 0;" "ccp1" } } */


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