This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][simplify-rtx][2/2] Simplify - (y ? -x : x) -> (!y ? -x : x


Hi all,

In this second patch I add the transformation mentioned in the subject to simplify-rtx.c.
In combination with the first patch to combine, combine_simplify_rtx now picks it up in the
testcase and does the right thing by not emitting an extra negate after the conditional negate
operation.

Bootstrapped and tested on aarch64, arm, x86_64.

Ok for trunk?

Thanks,
Kyrill


2015-07-16  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-16  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

    * gcc.target/aarch64/neg_abs_1.c: New test.
commit 5e8d7d5f431b30edfbc5f92004d5252a1ecfc19d
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Date:   Wed Jul 15 09:19:17 2015 +0100

    [simplify-rtx] Simplify - (y ? -x : x) -> (!y ? -x : x)

diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 91e4b9c..b20dd2d 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/gcc.target/aarch64/neg_abs_1.c b/gcc/testsuite/gcc.target/aarch64/neg_abs_1.c
new file mode 100644
index 0000000..cb2a387
--- /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\]*.*" } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]