Hello,I noticed we were only doing this transformation for floats and not for integers, so I took the chance to move it to match.pd. Regtested on ppc64le-redhat-linux.
2015-05-25 Marc Glisse <marc.gli...@inria.fr> * match.pd (swapped_tcc_comparison): New operator list. (-A CMP -B): New simplification. * fold-const.c (fold_comparison): Remove corresponding code. -- Marc Glisse
Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 223630) +++ gcc/fold-const.c (working copy) @@ -9176,38 +9176,25 @@ fold_comparison (location_t loc, enum tr if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype)) newtype = TREE_TYPE (targ1); /* Fold (double)float1 CMP (double)float2 into float1 CMP float2. */ if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0))) return fold_build2_loc (loc, code, type, fold_convert_loc (loc, newtype, targ0), fold_convert_loc (loc, newtype, targ1)); - /* (-a) CMP (-b) -> b CMP a */ - if (TREE_CODE (arg0) == NEGATE_EXPR - && TREE_CODE (arg1) == NEGATE_EXPR) - return fold_build2_loc (loc, code, type, TREE_OPERAND (arg1, 0), - TREE_OPERAND (arg0, 0)); - if (TREE_CODE (arg1) == REAL_CST) { REAL_VALUE_TYPE cst; cst = TREE_REAL_CST (arg1); - /* (-a) CMP CST -> a swap(CMP) (-CST) */ - if (TREE_CODE (arg0) == NEGATE_EXPR) - return fold_build2_loc (loc, swap_tree_comparison (code), type, - TREE_OPERAND (arg0, 0), - build_real (TREE_TYPE (arg1), - real_value_negate (&cst))); - /* IEEE doesn't distinguish +0 and -0 in comparisons. */ /* a CMP (-0) -> a CMP 0 */ if (REAL_VALUE_MINUS_ZERO (cst)) return fold_build2_loc (loc, code, type, arg0, build_real (TREE_TYPE (arg1), dconst0)); /* x != NaN is always true, other ops are always false. */ if (REAL_VALUE_ISNAN (cst) && ! HONOR_SNANS (arg1)) { Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 223630) +++ gcc/match.pd (working copy) @@ -31,20 +31,22 @@ along with GCC; see the file COPYING3. CONSTANT_CLASS_P tree_expr_nonnegative_p) /* Operator lists. */ (define_operator_list tcc_comparison lt le eq ne ge gt unordered ordered unlt unle ungt unge uneq ltgt) (define_operator_list inverted_tcc_comparison ge gt ne eq lt le ordered unordered ge gt le lt ltgt uneq) (define_operator_list inverted_tcc_comparison_with_nans unge ungt ne eq unlt unle ordered unordered ge gt le lt ltgt uneq) +(define_operator_list swapped_tcc_comparison + gt ge eq ne le lt unordered ordered ungt unge unlt unle uneq ltgt) /* Simplifications of operations with one constant operand and simplifications to constants or single values. */ (for op (plus pointer_plus minus bit_ior bit_xor) (simplify (op @0 integer_zerop) (non_lvalue @0))) @@ -973,20 +975,38 @@ along with GCC; see the file COPYING3. (bit_and (ordered @0 @0) (ordered @1 @1)) (if (types_match (@0, @1)) (ordered @0 @1))) (simplify (bit_ior:c (unordered @0 @0) (unordered:c@2 @0 @1)) @2) (simplify (bit_and:c (ordered @0 @0) (ordered:c@2 @0 @1)) @2) +/* -A CMP -B -> B CMP A. */ +(for cmp (tcc_comparison) + scmp (swapped_tcc_comparison) + (simplify + (cmp (negate @0) (negate @1)) + (if (FLOAT_TYPE_P (TREE_TYPE (@0)) + || (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))) + (scmp @0 @1))) + (simplify + (cmp (negate @0) CONSTANT_CLASS_P@1) + (if (FLOAT_TYPE_P (TREE_TYPE (@0)) + || (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))) + (with { tree tem = fold_unary (NEGATE_EXPR, TREE_TYPE (@0), @1); } + (if (tem && !TREE_OVERFLOW (tem)) + (scmp @0 { tem; })))))) + /* Simplification of math builtins. */ (define_operator_list LOG BUILT_IN_LOGF BUILT_IN_LOG BUILT_IN_LOGL) (define_operator_list EXP BUILT_IN_EXPF BUILT_IN_EXP BUILT_IN_EXPL) (define_operator_list LOG2 BUILT_IN_LOG2F BUILT_IN_LOG2 BUILT_IN_LOG2L) (define_operator_list EXP2 BUILT_IN_EXP2F BUILT_IN_EXP2 BUILT_IN_EXP2L) (define_operator_list LOG10 BUILT_IN_LOG10F BUILT_IN_LOG10 BUILT_IN_LOG10L) (define_operator_list EXP10 BUILT_IN_EXP10F BUILT_IN_EXP10 BUILT_IN_EXP10L) (define_operator_list POW BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL) (define_operator_list POW10 BUILT_IN_POW10F BUILT_IN_POW10 BUILT_IN_POW10L)