summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>2015-07-20 12:51:45 +0000
committerktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>2015-07-20 12:51:45 +0000
commit5ced42f848b676f2528f544c99283bb49d76c5a6 (patch)
treeb199851fd64c33575ae6c054bb768b03fabaf4d8
parentb8783ab25fcbe89a9268537eb21c9173ca79eb97 (diff)
downloadgcc-5ced42f848b676f2528f544c99283bb49d76c5a6.tar.gz
[simplify-rtx][2/2] Simplify - (y ? -x : x) -> (!y ? -x : x)
* simplify-rtx.c (simplify_unary_operation_1, NEG case): (neg (x ? (neg y) : y)) -> !x ? (neg y) : y. * gcc.target/aarch64/neg_abs_1.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@225997 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/simplify-rtx.c26
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/neg_abs_1.c17
4 files changed, 52 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5972a003571..addf8ad6a32 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2015-07-20 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+ * simplify-rtx.c (simplify_unary_operation_1, NEG case):
+ (neg (x ? (neg y) : y)) -> !x ? (neg y) : y.
+
+2015-07-20 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
* combine.c (combine_simplify_rtx): Move simplification step
before various transformations/substitutions.
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index fde99445e54..4332a42ced4 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -957,6 +957,32 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
if (GET_CODE (op) == NEG)
return XEXP (op, 0);
+ /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
+ If comparison is not reversible use
+ x ? y : (neg y). */
+ if (GET_CODE (op) == IF_THEN_ELSE)
+ {
+ rtx cond = XEXP (op, 0);
+ rtx true_rtx = XEXP (op, 1);
+ rtx false_rtx = XEXP (op, 2);
+
+ if ((GET_CODE (true_rtx) == NEG
+ && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
+ || (GET_CODE (false_rtx) == NEG
+ && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
+ {
+ if (reversed_comparison_code (cond, NULL_RTX) != UNKNOWN)
+ temp = reversed_comparison (cond, mode);
+ else
+ {
+ temp = cond;
+ std::swap (true_rtx, false_rtx);
+ }
+ return simplify_gen_ternary (IF_THEN_ELSE, mode,
+ mode, temp, true_rtx, false_rtx);
+ }
+ }
+
/* (neg (plus X 1)) can become (not X). */
if (GET_CODE (op) == PLUS
&& XEXP (op, 1) == const1_rtx)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 214ad673d89..9df1d41c151 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2015-07-20 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/aarch64/neg_abs_1.c: New test.
+
2015-07-18 Uros Bizjak <ubizjak@gmail.com>
PR target/66922
diff --git a/gcc/testsuite/gcc.target/aarch64/neg_abs_1.c b/gcc/testsuite/gcc.target/aarch64/neg_abs_1.c
new file mode 100644
index 00000000000..cb2a387088c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/neg_abs_1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-save-temps -O2" } */
+
+int
+f1 (int x)
+{
+ return x < 0 ? x : -x;
+}
+
+long long
+f2 (long long x)
+{
+ return x < 0 ? x : -x;
+}
+
+/* { dg-final { scan-assembler-not "\tneg\tw\[0-9\]*.*" } } */
+/* { dg-final { scan-assembler-not "\tneg\tx\[0-9\]*.*" } } */