aboutsummaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/match.pd')
-rw-r--r--gcc/match.pd60
1 files changed, 60 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 4e10d54..72860fb 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3976,6 +3976,66 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(cnd (logical_inverted_value truth_valued_p@0) @1 @2)
(cnd @0 @2 @1)))
+/* abs/negative simplifications moved from fold_cond_expr_with_comparison,
+ Need to handle (A - B) case as fold_cond_expr_with_comparison does.
+ Need to handle UN* comparisons.
+
+ None of these transformations work for modes with signed
+ zeros. If A is +/-0, the first two transformations will
+ change the sign of the result (from +0 to -0, or vice
+ versa). The last four will fix the sign of the result,
+ even though the original expressions could be positive or
+ negative, depending on the sign of A.
+
+ Note that all these transformations are correct if A is
+ NaN, since the two alternatives (A and -A) are also NaNs. */
+
+(for cnd (cond vec_cond)
+ /* A == 0 ? A : -A same as -A */
+ (for cmp (eq uneq)
+ (simplify
+ (cnd (cmp @0 zerop) @0 (negate@1 @0))
+ (if (!HONOR_SIGNED_ZEROS (type))
+ @1))
+ (simplify
+ (cnd (cmp @0 zerop) integer_zerop (negate@1 @0))
+ (if (!HONOR_SIGNED_ZEROS (type))
+ @1))
+ )
+ /* A != 0 ? A : -A same as A */
+ (for cmp (ne ltgt)
+ (simplify
+ (cnd (cmp @0 zerop) @0 (negate @0))
+ (if (!HONOR_SIGNED_ZEROS (type))
+ @0))
+ (simplify
+ (cnd (cmp @0 zerop) @0 integer_zerop)
+ (if (!HONOR_SIGNED_ZEROS (type))
+ @0))
+ )
+ /* A >=/> 0 ? A : -A same as abs (A) */
+ (for cmp (ge gt)
+ (simplify
+ (cnd (cmp @0 zerop) @0 (negate @0))
+ (if (!HONOR_SIGNED_ZEROS (type)
+ && !TYPE_UNSIGNED (type))
+ (abs @0))))
+ /* A <=/< 0 ? A : -A same as -abs (A) */
+ (for cmp (le lt)
+ (simplify
+ (cnd (cmp @0 zerop) @0 (negate @0))
+ (if (!HONOR_SIGNED_ZEROS (type)
+ && !TYPE_UNSIGNED (type))
+ (if (ANY_INTEGRAL_TYPE_P (type)
+ && !TYPE_OVERFLOW_WRAPS (type))
+ (with {
+ tree utype = unsigned_type_for (type);
+ }
+ (convert (negate (absu:utype @0))))
+ (negate (abs @0)))))
+ )
+)
+
/* -(type)!A -> (type)A - 1. */
(simplify
(negate (convert?:s (logical_inverted_value:s @0)))