public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][AArch64] Handle -|x| case using a single csneg
@ 2015-07-13  9:48 Kyrill Tkachov
  2015-07-14  0:38 ` Segher Boessenkool
  2015-07-14 11:04 ` pinskia
  0 siblings, 2 replies; 12+ messages in thread
From: Kyrill Tkachov @ 2015-07-13  9:48 UTC (permalink / raw)
  To: GCC Patches; +Cc: Marcus Shawcroft, Richard Earnshaw, James Greenhalgh

[-- Attachment #1: Type: text/plain, Size: 1174 bytes --]

Hi all,

For the testcase in the patch we were generating an extra neg instruction:
         cmp     w0, wzr
         csneg   w0, w0, w0, ge
         neg     w0, w0
         ret

instead of the optimal:
         cmp     w0, wzr
         csneg   w0, w0, w0, lt
         ret

The reason is that combine tries to merge the operation into a negation of an abs.
I considered teaching combine not to do that but it would require telling it that it shouldn't
do it if there is a conditional negate instruction. There's no optab for that though :(
Also, we already advertise that we have an abs optab, even though we expand to a compare and
a csneg anyway. This patch was the cleanest way I could do this. We just match the neg of an abs
and generate the same csneg sequence as for normal abs, just with the comparison condition inverted.

Bootstrapped and tested on aarch64.

Ok for trunk?
Thanks,
Kyrill

2015-07-13  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * config/aarch64/aarch64.md (*absneg2<mode>_insn): New
     define_and_split.

2015-07-13  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * gcc.target/aarch64/neg-abs_1.c: New test.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: abs-neg.patch --]
[-- Type: text/x-patch; name=abs-neg.patch, Size: 1998 bytes --]

commit 7527a76d25067ce4a5426e563e162487604ac6c1
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Date:   Thu Jul 9 16:54:23 2015 +0100

    [AArch64] Handle -|x| case using a single csneg

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index e6d0764..6664d1a 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -2333,6 +2333,29 @@ (define_expand "abs<mode>2"
   }
 )
 
+;; Combine will try merging (c > 0 ? -x : x) into (-|x|).  This isn't a good
+;; idea if the target has a conditional negate instruction and no integer
+;; abs instruction, but the midend doesn't have an optab for conditional neg
+;; and we advertise an optab for abs, so match that case here and emit the
+;; optimal CSNEG variant.
+(define_insn_and_split "*absneg2<mode>_insn"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+	(neg:GPI
+	  (abs:GPI (match_operand:GPI 1 "register_operand" "r"))))]
+  ""
+  "#"
+  ""
+  [(const_int 0)]
+  {
+    rtx ccreg = aarch64_gen_compare_reg (LT, operands[1], const0_rtx);
+    rtx x = gen_rtx_GE (VOIDmode, ccreg, const0_rtx);
+    emit_insn (gen_csneg3<mode>_insn (operands[0], x, operands[1],
+				       operands[1]));
+    DONE;
+  }
+  [(set_attr "type" "csel")]
+)
+
 (define_insn "neg<mode>2"
   [(set (match_operand:GPI 0 "register_operand" "=r,w")
 	(neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
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\]*.*" } } */

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-07-14 13:16 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-13  9:48 [PATCH][AArch64] Handle -|x| case using a single csneg Kyrill Tkachov
2015-07-14  0:38 ` Segher Boessenkool
2015-07-14  8:18   ` Kyrill Tkachov
2015-07-14 10:06     ` Andrew Pinski
2015-07-14 10:10       ` Andrew Pinski
2015-07-14 10:13       ` Kyrill Tkachov
2015-07-14 10:40         ` Andrew Pinski
2015-07-14 11:20           ` Kyrill Tkachov
2015-07-14 12:55     ` Segher Boessenkool
2015-07-14 13:16       ` Kyrill Tkachov
2015-07-14 11:04 ` pinskia
2015-07-14 12:39   ` Segher Boessenkool

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).