aboutsummaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
authorAndrew Pinski <apinski@marvell.com>2021-06-12 19:45:20 -0700
committerAndrew Pinski <apinski@marvell.com>2021-07-05 12:44:14 -0700
commit7d6979197274a662da7bdc564314afe8415865c1 (patch)
tree428f19f5ff32baafb5b7994f6ac8473a61659928 /gcc/match.pd
parenta50cecb20a10a729b3f5f157b154d28f9937a652 (diff)
downloadgcc-7d6979197274a662da7bdc564314afe8415865c1.zip
gcc-7d6979197274a662da7bdc564314afe8415865c1.tar.gz
gcc-7d6979197274a662da7bdc564314afe8415865c1.tar.bz2
Port most of the A CMP 0 ? A : -A to match
To improve phiopt and be able to remove abs_replacement, this ports most of "A CMP 0 ? A : -A" from fold_cond_expr_with_comparison to match.pd. There is a few extra changes that are needed to remove the "A CMP 0 ? A : -A" part from fold_cond_expr_with_comparison: * Need to handle (A - B) case * Need to handle UN* comparisons. I will handle those in a different patch. Note phi-opt-15.c test needed to be updated as we get ABSU now instead of not getting ABS. When ABSU was added phiopt was not updated even to use ABSU instead of not creating ABS. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/ChangeLog: PR tree-optimization/101039 * match.pd (A CMP 0 ? A : -A): New patterns. * tree-ssa-phiopt.c (abs_replacement): Delete function. (tree_ssa_phiopt_worker): Don't call abs_replacement. Update comment about abs_replacement. gcc/testsuite/ChangeLog: PR tree-optimization/101039 * gcc.dg/tree-ssa/phi-opt-15.c: Update test to expect ABSU and still not expect ABS_EXPR. * gcc.dg/tree-ssa/phi-opt-23.c: New test. * gcc.dg/tree-ssa/phi-opt-24.c: New test.
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)))