This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Simplify -x<0 to x>0
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 24 May 2015 15:33:14 +0200 (CEST)
- Subject: Simplify -x<0 to x>0
- Authentication-results: sourceware.org; auth=none
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.glisse@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)