]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[ARC] Recognise add_n and sub_n in combine again
authoraburgess <aburgess@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 31 May 2017 13:15:33 +0000 (13:15 +0000)
committeraburgess <aburgess@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 31 May 2017 13:15:33 +0000 (13:15 +0000)
Since the combine pass canonicalises shift-add insns using plus and
ashift (as opposed to plus and mult which it previously used to do), it
no longer creates *add_n or *sub_n insns, as the patterns match plus and
mult only. The outcome of this is that some opportunities to generate
add{1,2,3} and sub{1,2,3} instructions are missed.

This change adds additional *add_n and *sub_n insns that match the
plus-ashift pattern. The original *add_n and *sub_n insns are still left
in, as they are sometimes generated later on by constant propagation.
The idea of adding these insns is modelled on the changes in:

  https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01882.html

which addresses a similar issue for the PA target.

For the small test cases that are added, even if the combine pass misses
the opportunity to generate addN or subN, constant propagation manages
to do so, so the rtl of the combine pass is checked.

gcc/ChangeLog:

        * config/arc/arc.c (arc_print_operand): Handle constant operands.
        (arc_rtx_costs): Add costs for new patterns.
        * config/arc/arc.md: Additional *add_n and *sub_n patterns.
        * config/arc/predicates.md: Add _1_2_3_operand predicate.

gcc/testsuite/ChangeLog:

        * gcc.target/arc/add_n-combine.c: New test.
        * gcc.target/arc/sub_n-combine.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@248735 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arc/arc.c
gcc/config/arc/arc.md
gcc/config/arc/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arc/add_n-combine.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/sub_n-combine.c [new file with mode: 0644]

index 01c06b16e1e6dff33a533d237802c5a2edd35e96..f42b287413ba21c80589c3dbdf7559661ed3139c 100644 (file)
@@ -1,3 +1,10 @@
+2017-05-31  Graham Markall  <graham.markall@embecosm.com>
+
+       * config/arc/arc.c (arc_print_operand): Handle constant operands.
+       (arc_rtx_costs): Add costs for new patterns.
+       * config/arc/arc.md: Additional *add_n and *sub_n patterns.
+       * config/arc/predicates.md: Add _1_2_3_operand predicate.
+
 2017-05-31  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * tree-ssa-strlen.c (get_next_strinfo): New function.
index 91c28e7355412b211c9141aa6d67d2e25ee79760..42730d55d8049584473cd6fb690e1fe6be757f1a 100644 (file)
@@ -3483,6 +3483,14 @@ arc_print_operand (FILE *file, rtx x, int code)
 
       return;
 
+    case 'c':
+      if (GET_CODE (x) == CONST_INT)
+        fprintf (file, "%d", INTVAL (x) );
+      else
+        output_operand_lossage ("invalid operands to %%c code");
+
+      return;
+
     case 'M':
       if (GET_CODE (x) == CONST_INT)
        fprintf (file, "%d",exact_log2(~INTVAL (x)) );
@@ -4895,8 +4903,10 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
        *total = COSTS_N_INSNS (2);
       return false;
     case PLUS:
-      if (GET_CODE (XEXP (x, 0)) == MULT
-         && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
+      if ((GET_CODE (XEXP (x, 0)) == ASHIFT
+          && _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
+          || (GET_CODE (XEXP (x, 0)) == MULT
+              && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)))
        {
          *total += (rtx_cost (XEXP (x, 1), mode, PLUS, 0, speed)
                     + rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed));
@@ -4904,8 +4914,10 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
        }
       return false;
     case MINUS:
-      if (GET_CODE (XEXP (x, 1)) == MULT
-         && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
+      if ((GET_CODE (XEXP (x, 1)) == ASHIFT
+          && _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
+          || (GET_CODE (XEXP (x, 1)) == MULT
+              && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)))
        {
          *total += (rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed)
                     + rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed));
index edb983f1b2d021981b4acc404e1606e8063e4d12..ec783a047f22001f951d0ef698e45b1dd5654623 100644 (file)
       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
    (set (match_dup 3) (match_dup 4))])
 
+(define_insn "*add_n"
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
+       (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
+                           (match_operand:SI 2 "_1_2_3_operand" ""))
+                (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
+  ""
+  "add%c2%? %0,%3,%1%&"
+  [(set_attr "type" "shift")
+   (set_attr "length" "*,4,4,8,4,8")
+   (set_attr "predicable" "yes,yes,no,no,no,no")
+   (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
+   (set_attr "iscompact" "maybe,false,false,false,false,false")])
+
 (define_insn "*add_n"
   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
 
 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
 ;; what synth_mult likes.
+(define_insn "*sub_n"
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
+       (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
+                 (ashift:SI (match_operand:SI 2 "register_operand" "c,c,c")
+                            (match_operand:SI 3 "_1_2_3_operand" ""))))]
+  ""
+  "sub%c3%? %0,%1,%2"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4,4,8")
+   (set_attr "predicable" "yes,no,no")
+   (set_attr "cond" "canuse,nocond,nocond")
+   (set_attr "iscompact" "false")])
+
 (define_insn "*sub_n"
   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
        (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
index 7ddec9149d1340d3b70d89fe9e686c27dfd8e7c4..1f6643853c583bfa66b8126976c3c94c9233aa96 100644 (file)
            (match_test "TARGET_ARC700 || TARGET_EA_SET")))
 )
 
+(define_predicate "_1_2_3_operand"
+  (and (match_code "const_int")
+       (match_test "INTVAL (op) == 1 || INTVAL (op) == 2 || INTVAL (op) == 3"))
+)
+
 (define_predicate "_2_4_8_operand"
   (and (match_code "const_int")
        (match_test "INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8"))
index 8b74dc3364a211c0d39739efaa1f17a9b526d8ed..fa0bbef93a7bc868b142a20671b63c31d182e793 100644 (file)
@@ -1,3 +1,8 @@
+2017-05-31  Graham Markall  <graham.markall@embecosm.com>
+
+       * gcc.target/arc/add_n-combine.c: New test.
+       * gcc.target/arc/sub_n-combine.c: New test.
+
 2017-05-31  Richard Biener  <rguenther@suse.de>
 
        PR target/80880
diff --git a/gcc/testsuite/gcc.target/arc/add_n-combine.c b/gcc/testsuite/gcc.target/arc/add_n-combine.c
new file mode 100644 (file)
index 0000000..db6454f
--- /dev/null
@@ -0,0 +1,48 @@
+/* { dg-do compile }  */
+/* { dg-options "-O2 -fdump-rtl-combine" }  */
+
+struct b1 {
+      char c;
+      char bg;
+};
+
+struct bj1 {
+  char bk;
+  struct b1 bn[];
+};
+
+struct b2 {
+      short c;
+      char bg;
+};
+
+struct bj2 {
+  short bk;
+  struct b2 bn[];
+};
+
+struct b3 {
+      int c;
+      char bg;
+};
+
+struct bj3 {
+  int bk;
+  struct b3 bn[];
+};
+
+
+struct bj1 at1;
+struct bj2 at2;
+struct bj3 at3;
+
+int bu;
+void a();
+
+void f() {
+  a(at1.bn[bu]);
+  a(at2.bn[bu]);
+  a(at3.bn[bu]);
+}
+
+/* { dg-final { scan-rtl-dump-times "\\*add_n" 3 "combine" } } */
diff --git a/gcc/testsuite/gcc.target/arc/sub_n-combine.c b/gcc/testsuite/gcc.target/arc/sub_n-combine.c
new file mode 100644 (file)
index 0000000..4e227e4
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile }  */
+/* { dg-options "-O2 -fdump-rtl-combine" }  */
+
+int a;
+
+double b1() {
+  int c = a << 1;
+  return 1 - c;
+}
+
+double b2() {
+  int c = a << 2;
+  return 1 - c;
+}
+
+double b3() {
+  int c = a << 3;
+  return 1 - c;
+}
+
+/* { dg-final { scan-rtl-dump-times "\\*sub_n" 3 "combine" } } */