This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][simplify-rtx][2/2] Simplify - (y ? -x : x) -> (!y ? -x : x
- From: Kyrill Tkachov <kyrylo dot tkachov at arm dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Segher Boessenkool <segher at kernel dot crashing dot org>, Andrew Pinski <apinski at cavium dot com>, Eric Botcazou <ebotcazou at adacore dot com>
- Date: Thu, 16 Jul 2015 16:25:16 +0100
- Subject: [PATCH][simplify-rtx][2/2] Simplify - (y ? -x : x) -> (!y ? -x : x
- Authentication-results: sourceware.org; auth=none
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\]*.*" } } */