[AArch64] Add ANDS pattern for CMP+ZERO_EXTEND
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Thu, 1 Sep 2016 09:03:52 +0000 (09:03 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Thu, 1 Sep 2016 09:03:52 +0000 (09:03 +0000)
* config/aarch64/aarch64.md (*ands<mode>_compare0): New pattern.
* config/aarch64/aarch64.c (aarch64_select_cc_mode): Return CC_NZmode
for comparisons of integer ZERO_EXTEND against zero.

* gcc.target/aarch64/ands_3.c: New test.

From-SVN: r239919

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/ands_3.c [new file with mode: 0644]

index 9f90359170ebdb5efde545f90a7848b7f63b759f..bf5c54901e7930fbd8d378011250d5c21b9cdff5 100644 (file)
@@ -1,3 +1,9 @@
+2016-09-01  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/aarch64/aarch64.md (*ands<mode>_compare0): New pattern.
+       * config/aarch64/aarch64.c (aarch64_select_cc_mode): Return CC_NZmode
+       for comparisons of integer ZERO_EXTEND against zero.
+
 2016-09-01  Eric Botcazou  <ebotcazou@adacore.com>
 
        * config/i386/i386.c (ix86_option_override_internal): Also disable the
index 3e663eb5f13a7909564d085b73ae55685eea4bea..e813d66b40a6a9abce0a913f3d643153917bfd05 100644 (file)
@@ -4264,6 +4264,14 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
       && (GET_MODE (x) == HImode || GET_MODE (x) == QImode))
     return CC_NZmode;
 
+  /* Similarly, comparisons of zero_extends from shorter modes can
+     be performed using an ANDS with an immediate mask.  */
+  if (y == const0_rtx && GET_CODE (x) == ZERO_EXTEND
+      && (GET_MODE (x) == SImode || GET_MODE (x) == DImode)
+      && (GET_MODE (XEXP (x, 0)) == HImode || GET_MODE (XEXP (x, 0)) == QImode)
+      && (code == EQ || code == NE))
+    return CC_NZmode;
+
   if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode)
       && y == const0_rtx
       && (code == EQ || code == NE || code == LT || code == GE)
index c95258b71033451ab1d5f4826e0bfa0044edc704..6afaf906915efe58a089ccb8f2b035a9f46555d3 100644 (file)
   [(set_attr "type" "alus_imm")]
 )
 
+(define_insn "*ands<mode>_compare0"
+  [(set (reg:CC_NZ CC_REGNUM)
+       (compare:CC_NZ
+        (zero_extend:GPI (match_operand:SHORT 1 "register_operand" "r"))
+        (const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+       (zero_extend:GPI (match_dup 1)))]
+  ""
+  "ands\\t%<GPI:w>0, %<GPI:w>1, <short_mask>"
+  [(set_attr "type" "alus_imm")]
+)
+
 (define_insn "*and<mode>3nr_compare0"
   [(set (reg:CC_NZ CC_REGNUM)
        (compare:CC_NZ
index 864215d9dc4fba3a10a02bdf6a290a306297c273..82f3daaa9f54c3efdfe58a65bb8afdd6d8eec691 100644 (file)
@@ -1,3 +1,7 @@
+2016-09-01  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * gcc.target/aarch64/ands_3.c: New test.
+
 2016-08-31  Jakub Jelinek  <jakub@redhat.com>
 
        PR fortran/77352
diff --git a/gcc/testsuite/gcc.target/aarch64/ands_3.c b/gcc/testsuite/gcc.target/aarch64/ands_3.c
new file mode 100644 (file)
index 0000000..42cb7f0
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+f9 (unsigned char x, int y)
+{
+  if (y > 1 && x == 0)
+    return 10;
+  return x;
+}
+
+/* { dg-final { scan-assembler "ands\t(x|w)\[0-9\]+,\[ \t\]*(x|w)\[0-9\]+,\[ \t\]*255" } } */