[PATCH] Improve EQ_EXPR/NE_EXPR folding (PR middle-end/38878)

Jakub Jelinek jakub@redhat.com
Thu Feb 3 18:11:00 GMT 2011


Hi!

== and != doesn't care about signedness of the operands, so we
can IMHO use STRIP_NOPS instead of just STRIP_SIGN_NOPS.
Additionally, for X +- C == X and C - X == X folding we can also
strip nops from the +/-/p+ operand for the purpose of operand_equal_p
checking.  This together fixes PR38878 regression (P2), though I'm
not 100% sure we want to do that this late, perhaps we can defer
it till stage1.

Nevertheless, bootstrapped/regtested on x86_64-linux and i686-linux.

2011-02-03  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/38878
	* fold-const.c (fold_binary_loc) <case EQ_EXPR, NE_EXPR>: Add
	STRIP_NOPS on arg0 and arg1.  When optimizing X +- C == X
	and C - X == X also strip nops from +/-/p+ operand.
	When optimizing -X == C, fold C to arg0's type.

	* gcc.dg/tree-ssa/foldaddr-1.c: Remove xfail.

--- gcc/fold-const.c.jj	2010-12-02 11:51:31.000000000 +0100
+++ gcc/fold-const.c	2011-02-03 15:45:27.000000000 +0100
@@ -12111,6 +12111,9 @@ fold_binary_loc (location_t loc,
 
     case EQ_EXPR:
     case NE_EXPR:
+      STRIP_NOPS (arg0);
+      STRIP_NOPS (arg1);
+
       tem = fold_comparison (loc, code, type, op0, op1);
       if (tem != NULL_TREE)
 	return tem;
@@ -12193,7 +12196,8 @@ fold_binary_loc (location_t loc,
       /* Similarly for a NEGATE_EXPR.  */
       if (TREE_CODE (arg0) == NEGATE_EXPR
 	  && TREE_CODE (arg1) == INTEGER_CST
-	  && 0 != (tem = negate_expr (arg1))
+	  && 0 != (tem = negate_expr (fold_convert_loc (loc, TREE_TYPE (arg0),
+							arg1)))
 	  && TREE_CODE (tem) == INTEGER_CST
 	  && !TREE_OVERFLOW (tem))
 	return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), tem);
@@ -12213,7 +12217,9 @@ fold_binary_loc (location_t loc,
       if ((TREE_CODE (arg0) == PLUS_EXPR
 	   || TREE_CODE (arg0) == POINTER_PLUS_EXPR
 	   || TREE_CODE (arg0) == MINUS_EXPR)
-	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
+	  && operand_equal_p (tree_strip_nop_conversions (TREE_OPERAND (arg0,
+									0)),
+			      arg1, 0)
 	  && (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
 	      || POINTER_TYPE_P (TREE_TYPE (arg0))))
 	{
@@ -12229,7 +12235,9 @@ fold_binary_loc (location_t loc,
       /* Transform comparisons of the form C - X CMP X if C % 2 == 1.  */
       if (TREE_CODE (arg0) == MINUS_EXPR
 	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == INTEGER_CST
-	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0)
+	  && operand_equal_p (tree_strip_nop_conversions (TREE_OPERAND (arg0,
+									1)),
+			      arg1, 0)
 	  && (TREE_INT_CST_LOW (TREE_OPERAND (arg0, 0)) & 1) == 1)
 	{
 	  return omit_two_operands_loc (loc, type,
--- gcc/testsuite/gcc.dg/tree-ssa/foldaddr-1.c.jj	2009-01-26 15:24:36.000000000 +0100
+++ gcc/testsuite/gcc.dg/tree-ssa/foldaddr-1.c	2011-02-03 15:51:24.000000000 +0100
@@ -11,6 +11,6 @@ int foo(char *b)
 /* Folding should have determined that the two addresses were
    not identical and thus collapsed the function into a trivial
    "return 0".  */
-/* { dg-final { scan-tree-dump-times "return 0" 1 "original" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "return 0" 1 "original" } } */
 /* { dg-final { cleanup-tree-dump "original" } } */
 

	Jakub



More information about the Gcc-patches mailing list