[simplify-rtx][2/2] Simplify - (y ? -x : x) -> (!y ? -x : x)
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Mon, 20 Jul 2015 12:51:45 +0000 (12:51 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Mon, 20 Jul 2015 12:51:45 +0000 (12:51 +0000)
* 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.

From-SVN: r225997

gcc/ChangeLog
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/neg_abs_1.c [new file with mode: 0644]

index 5972a00357120d4c9090ad3be1e94550680c2bcb..addf8ad6a32dd24d3043e875be8e5194ca5b54ed 100644 (file)
@@ -1,3 +1,8 @@
+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
index fde99445e54d6f755d10e3fee1624df650e4581e..4332a42ced4ac9a6c323f60f102016b223d0e177 100644 (file)
@@ -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)
index 214ad673d89a18d56468ee2c9abf539e73e81d01..9df1d41c151c9c7120bf5ef3c347abaf8eee168e 100644 (file)
@@ -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 (file)
index 0000000..cb2a387
--- /dev/null
@@ -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\]*.*" } } */