[backport from gcc-4.7/trunk ] Date: Thu, 3 Feb 2011 19:11:31 +0100 From: Jakub Jelinek Subject: [PATCH] Improve EQ_EXPR/NE_EXPR folding (PR middle-end/38878) List-Archive: 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. gcc/ 2011-03-14 Jakub Jelinek PR middle-end/38878 * fold-const.c (fold_binary_loc) : 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/testsuite/ 2011-03-14 Jakub Jelinek PR middle-end/38878 * gcc.dg/tree-ssa/foldaddr-1.c: Remove xfail. --- gcc-4.6-20110312/gcc/fold-const.c.~1~ 2011-03-08 11:43:10.000000000 +0100 +++ gcc-4.6-20110312/gcc/fold-const.c 2011-03-16 15:57:25.000000000 +0100 @@ -12112,6 +12112,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; @@ -12194,7 +12197,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); @@ -12214,7 +12218,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)))) { @@ -12230,7 +12236,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-4.6-20110312/gcc/testsuite/gcc.dg/tree-ssa/foldaddr-1.c.~1~ 2009-01-17 02:31:44.000000000 +0100 +++ gcc-4.6-20110312/gcc/testsuite/gcc.dg/tree-ssa/foldaddr-1.c 2011-03-16 15:57:25.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" } } */