[AArch64] Use SUBS for parallel subtraction and comparison with immediate
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Mon, 5 Jun 2017 08:49:59 +0000 (08:49 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Mon, 5 Jun 2017 08:49:59 +0000 (08:49 +0000)
* config/aarch64/aarch64.md (sub<mode>3_compare1_imm): New define_insn.
(peephole2): New peephole2 to emit the above.
* config/aarch64/predicates.md (aarch64_sub_immediate): New predicate.

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

From-SVN: r248870

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

index eb7e9ca97744363cc7d42bd11b5ca059466883ff..1921a6fd522bb3340390ecff1fed8a3ca7dc20d4 100644 (file)
@@ -1,3 +1,9 @@
+2017-06-05  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/aarch64/aarch64.md (sub<mode>3_compare1_imm): New define_insn.
+       (peephole2): New peephole2 to emit the above.
+       * config/aarch64/predicates.md (aarch64_sub_immediate): New predicate.
+
 2017-06-05  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/aarch64/aarch64.c (define_peephole2 above
index 475c6d7e85dd7a445ff9d757c246343b8f88e620..d89df66fecc9873b84b6bf34d01792dd818443e6 100644 (file)
   [(set_attr "type" "alus_sreg")]
 )
 
+(define_insn "sub<mode>3_compare1_imm"
+  [(set (reg:CC CC_REGNUM)
+       (compare:CC
+         (match_operand:GPI 1 "register_operand" "r")
+         (match_operand:GPI 3 "const_int_operand" "n")))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+       (plus:GPI (match_dup 1)
+                 (match_operand:GPI 2 "aarch64_sub_immediate" "J")))]
+  "INTVAL (operands[3]) == -INTVAL (operands[2])"
+  "subs\\t%<w>0, %<w>1, #%n2"
+  [(set_attr "type" "alus_sreg")]
+)
+
 (define_peephole2
   [(set (match_operand:GPI 0 "register_operand")
        (minus:GPI (match_operand:GPI 1 "aarch64_reg_or_zero")
   }
 )
 
+(define_peephole2
+  [(set (match_operand:GPI 0 "register_operand")
+       (plus:GPI (match_operand:GPI 1 "register_operand")
+                 (match_operand:GPI 2 "aarch64_sub_immediate")))
+   (set (reg:CC CC_REGNUM)
+       (compare:CC
+         (match_dup 1)
+         (match_operand:GPI 3 "const_int_operand")))]
+  "!reg_overlap_mentioned_p (operands[0], operands[1])
+   && INTVAL (operands[3]) == -INTVAL (operands[2])"
+  [(const_int 0)]
+  {
+    emit_insn (gen_sub<mode>3_compare1_imm (operands[0], operands[1],
+                                        operands[2], operands[3]));
+    DONE;
+  }
+)
+
 (define_insn "*sub_<shift>_<mode>"
   [(set (match_operand:GPI 0 "register_operand" "=r")
        (minus:GPI (match_operand:GPI 3 "register_operand" "r")
index 8e3ea9b469659410fe3d6ff52d9d590a711a46fa..cd7ded986630c14ed6d42618b2a1f9baa0cbd192 100644 (file)
 (define_predicate "aarch64_fp_vec_pow2"
   (match_test "aarch64_vec_fpconst_pow_of_2 (op) > 0"))
 
+(define_predicate "aarch64_sub_immediate"
+  (and (match_code "const_int")
+       (match_test "aarch64_uimm12_shift (-INTVAL (op))")))
+
 (define_predicate "aarch64_plus_immediate"
   (and (match_code "const_int")
        (ior (match_test "aarch64_uimm12_shift (INTVAL (op))")
index 027a802d04df497ba71782f0cc6873d7c6e10df8..5fa7850015f298d70ffdf2418453a07258b45c2a 100644 (file)
@@ -1,3 +1,7 @@
+2017-06-05  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * gcc.target/aarch64/subs_compare_2.c: New test.
+
 2017-06-05  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * gcc.target/aarch64/subs_compare_1.c: New test.
diff --git a/gcc/testsuite/gcc.target/aarch64/subs_compare_2.c b/gcc/testsuite/gcc.target/aarch64/subs_compare_2.c
new file mode 100644 (file)
index 0000000..60c6d9e
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (int a, int b)
+{
+  int x = a - 4;
+  if (a < 4)
+    return x;
+  else
+    return 0;
+}
+
+/* { dg-final { scan-assembler-times "subs\\tw\[0-9\]+, w\[0-9\]+, #4" 1 } } */
+/* { dg-final { scan-assembler-not "cmp\\tw\[0-9\]+, w\[0-9\]+" } } */