Use CSINC instead of CSEL to return 1 (AArch64)
authorIan Bolton <ian.bolton@arm.com>
Mon, 12 Nov 2012 19:39:46 +0000 (19:39 +0000)
committerIan Bolton <ibolton@gcc.gnu.org>
Mon, 12 Nov 2012 19:39:46 +0000 (19:39 +0000)
From-SVN: r193452

gcc/ChangeLog
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/constraints.md
gcc/config/aarch64/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/csinc-2.c [new file with mode: 0644]

index c03a235..ac11617 100644 (file)
@@ -1,5 +1,13 @@
 2012-11-12  Ian Bolton  <ian.bolton@arm.com>
 
+       * config/aarch64/aarch64.md (cmov<mode>_insn): Emit CSINC when
+       one of the alternatives is constant 1.
+       * config/aarch64/constraints.md: New constraint.
+       * config/aarch64/predicates.md: Rename predicate
+       aarch64_reg_zero_or_m1 to aarch64_reg_zero_or_m1_or_1.
+
+2012-11-12  Ian Bolton  <ian.bolton@arm.com>
+
        * config/aarch64/aarch64.md (*compare_neg<mode>): New pattern.
 
 2012-11-12  Tobias Burnus  <burnus@net-b.de>
index 077a89e..a9a8b5f 100644 (file)
 )
 
 (define_insn "*cmov<mode>_insn"
-  [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r")
+  [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
        (if_then_else:ALLI
         (match_operator 1 "aarch64_comparison_operator"
          [(match_operand 2 "cc_register" "") (const_int 0)])
-        (match_operand:ALLI 3 "aarch64_reg_zero_or_m1" "rZ,rZ,UsM,UsM")
-        (match_operand:ALLI 4 "aarch64_reg_zero_or_m1" "rZ,UsM,rZ,UsM")))]
-  ""
-  ;; Final alternative should be unreachable, but included for completeness
+        (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
+        (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
+  "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
+     || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
+  ;; Final two alternatives should be unreachable, but included for completeness
   "@
    csel\\t%<w>0, %<w>3, %<w>4, %m1
    csinv\\t%<w>0, %<w>3, <w>zr, %m1
    csinv\\t%<w>0, %<w>4, <w>zr, %M1
-   mov\\t%<w>0, -1"
+   csinc\\t%<w>0, %<w>3, <w>zr, %m1
+   csinc\\t%<w>0, %<w>4, <w>zr, %M1
+   mov\\t%<w>0, -1
+   mov\\t%<w>0, 1"
   [(set_attr "v8type" "csel")
    (set_attr "mode" "<MODE>")]
 )
index fe61307..dae4b94 100644 (file)
   A constraint that matches the immediate constant -1."
   (match_test "op == constm1_rtx"))
 
+(define_constraint "Ui1"
+  "@internal
+  A constraint that matches the immediate constant +1."
+  (match_test "op == const1_rtx"))
+
 (define_constraint "Ui3"
   "@internal
   A constraint that matches the integers 0...4."
index 6f79039..80f6ce2 100644 (file)
        (ior (match_operand 0 "register_operand")
            (match_test "op == const0_rtx"))))
 
-(define_predicate "aarch64_reg_zero_or_m1"
+(define_predicate "aarch64_reg_zero_or_m1_or_1"
   (and (match_code "reg,subreg,const_int")
        (ior (match_operand 0 "register_operand")
            (ior (match_test "op == const0_rtx")
-                (match_test "op == constm1_rtx")))))
+                (ior (match_test "op == constm1_rtx")
+                     (match_test "op == const1_rtx"))))))
 
 (define_predicate "aarch64_fp_compare_operand"
   (ior (match_operand 0 "register_operand")
index 3cda5b6..9c93370 100644 (file)
@@ -1,5 +1,9 @@
 2012-11-12  Ian Bolton  <ian.bolton@arm.com>
 
+       * gcc.target/aarch64/csinc-2.c: New test.
+
+2012-11-12  Ian Bolton  <ian.bolton@arm.com>
+
        * gcc.target/aarch64/cmn.c: New test.
        * gcc.target/aarch64/adds.c: New test.
        * gcc.target/aarch64/subs.c: New test.
diff --git a/gcc/testsuite/gcc.target/aarch64/csinc-2.c b/gcc/testsuite/gcc.target/aarch64/csinc-2.c
new file mode 100644 (file)
index 0000000..1b4eb7e
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (int a, int b)
+{
+  return (a < b) ? 1 : 7;
+  /* { dg-final { scan-assembler "csinc\tw\[0-9\].*wzr" } } */
+}
+
+typedef long long s64;
+
+s64
+foo2 (s64 a, s64 b)