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][AArch64] PR rtl-optimization/68796: Add patterns for QImode and HImode comparison with zero


Hi all,

This is an aarch64-specific approach to fixing the issue I raised in the thread at:
https://gcc.gnu.org/ml/gcc-patches/2015-12/msg01779.html

The guidance there was to define aarch64 patterns for comparing QImode and HImode registers
against zero.  This is a simple pattern to write and it maps down to a TST instruction
with the mode mask immediate for each of the short modes.

On aarch64 it has the exact same codegen effect as the combine patch I proposed in the
thread above. For example:

With this patch for the testcases:
int
f255 (int x)
{
  if (x & 255)
    return 1;
  return x;
}

int
foo (long x)
{
   return ((short) x != 0) ? x : 1;
}

we now generate for aarch64 at -O2:
f255:
        tst     x0, 255
        csinc   w0, w0, wzr, eq
        ret

and
foo:
        tst     x0, 65535
        csinc   x0, x0, xzr, ne
        ret


instead of the previous:
f255:
        and     w1, w0, 255
        cmp     w1, wzr
        csinc   w0, w0, wzr, eq
        ret

foo:
        sxth    w1, w0
        cmp     w1, wzr
        csinc   x0, x0, xzr, ne
        ret


Bootstrapped and tested on aarch64-none-linux-gnu.
Ok for trunk?

Thanks,
Kyrill


2016-01-07  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

    PR rtl-optimization/68796
    * config/aarch64/aarch64.md (*and<mode>_compare0): New pattern.
    * config/aarch64/aarch64.c (aarch64_select_cc_mode): Handle HImode
    and QImode comparisons against zero with CC_NZmode.
    * config/aarch64/iterators.md (short_mask): New mode_attr.

2016-01-07  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

    PR rtl-optimization/68796
    * gcc.target/aarch64/tst_5.c: New test.
    * gcc.target/aarch64/tst_6.c: Likewise.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 0284406334e1a6ea4c0474873bea4eb69283b572..914af423569bcabd5e32160f872e33057408e2d4 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -4143,6 +4143,13 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
 	}
     }
 
+  /* Equality comparisons of short modes against zero can be performed
+     using the TST instruction with the appropriate bitmask.  */
+  if (y == const0_rtx && REG_P (x)
+      && (code == EQ || code == NE)
+      && (GET_MODE (x) == HImode || GET_MODE (x) == QImode))
+    return CC_NZmode;
+
   if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode)
       && y == const0_rtx
       && (code == EQ || code == NE || code == LT || code == GE)
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index a91ed9be082ab0f321a4880845560f72386f0ec3..9471091408ff2146ad57ccf4ddc983424318a5a5 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -3687,6 +3687,16 @@ (define_expand "ctz<mode>2"
   }
 )
 
+(define_insn "*and<mode>_compare0"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (match_operand:SHORT 0 "register_operand" "r")
+	 (const_int 0)))]
+  ""
+  "tst\\t%<w>0, <short_mask>"
+  [(set_attr "type" "alus_imm")]
+)
+
 (define_insn "*and<mode>3nr_compare0"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 549d47a7a5d88c142343cdc5c952972069af1c0c..49598a2cd9356d2ff9920544c16f48bbb30022fb 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -345,6 +345,8 @@ (define_mode_attr w [(QI "w") (HI "w") (SI "w") (DI "x") (SF "s") (DF "d")])
 (define_mode_attr w1 [(SF "w") (DF "x")])
 (define_mode_attr w2 [(SF "x") (DF "w")])
 
+(define_mode_attr short_mask [(HI "65535") (QI "255")])
+
 ;; For constraints used in scalar immediate vector moves
 (define_mode_attr hq [(HI "h") (QI "q")])
 
diff --git a/gcc/testsuite/gcc.target/aarch64/tst_5.c b/gcc/testsuite/gcc.target/aarch64/tst_5.c
new file mode 100644
index 0000000000000000000000000000000000000000..0de40a6c47a7d63c1b7a81aeba438a096c0041b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tst_5.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+f255 (int x)
+{
+  if (x & 255)
+    return 1;
+  return x;
+}
+
+int
+f65535 (int x)
+{
+  if (x & 65535)
+    return 1;
+  return x;
+}
+
+/* { dg-final { scan-assembler "tst\t(x|w)\[0-9\]+,\[ \t\]*255" } } */
+/* { dg-final { scan-assembler "tst\t(x|w)\[0-9\]+,\[ \t\]*65535" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tst_6.c b/gcc/testsuite/gcc.target/aarch64/tst_6.c
new file mode 100644
index 0000000000000000000000000000000000000000..f15ec114c391fed79cc43b7740fde83fb3d4ea53
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tst_6.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (long x)
+{
+   return ((short) x != 0) ? x : 1;
+}
+
+/* { dg-final { scan-assembler "tst\t(x|w)\[0-9\]+,\[ \t\]*65535" } } */

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