]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/54236 ([SH] Improve addc and subc insn utilization)
authorOleg Endo <olegendo@gcc.gnu.org>
Wed, 21 May 2014 08:06:06 +0000 (08:06 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Wed, 21 May 2014 08:06:06 +0000 (08:06 +0000)
gcc/
        PR target/54236
        * config/sh/sh.md (*addc_r_1): Rename to addc_t_r.  Remove empty
        constraints.
        (*addc_r_t): Add new insn_and_split.

gcc/testsuite/
        PR target/54236
        * gcc.target/sh/pr54236-3.c: New.

From-SVN: r210682

gcc/ChangeLog
gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/pr54236-3.c [new file with mode: 0644]

index f167e76e14007a8aa4c0ad6042f82ec4ebc45c50..e2e3dd379acd9ecff5008f6d4f4e65fee0cf913c 100644 (file)
@@ -1,3 +1,10 @@
+2014-05-21  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/54236
+       * config/sh/sh.md (*addc_r_1): Rename to addc_t_r.  Remove empty
+       constraints.
+       (*addc_r_t): Add new insn_and_split.
+
 2014-05-21  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/61252
index 0250f9231ec2f5546335a2c703ffa89bbf11a35a..d998af96ec831ddaf89a59d79de93707e1ba4b74 100644 (file)
 ;; We allow a reg or 0 for one of the operands in order to be able to
 ;; do 'reg + T' sequences.  Reload will load the constant 0 into the reg
 ;; as needed.
+;; FIXME: The load of constant 0 should be split out before reload, or else
+;; it will be difficult to hoist or combine the constant load.
 (define_insn "*addc"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
        (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
 ;; can be scheduled much better since the load of the constant can be
 ;; done earlier, before any comparison insns that store the result in
 ;; the T bit.
-(define_insn_and_split "*addc_r_1"
-  [(set (match_operand:SI 0 "arith_reg_dest" "")
-       (plus:SI (match_operand:SI 1 "t_reg_operand" "")
-                (match_operand:SI 2 "arith_reg_operand" "")))
+(define_insn_and_split "*addc_t_r"
+  [(set (match_operand:SI 0 "arith_reg_dest")
+       (plus:SI (match_operand:SI 1 "t_reg_operand")
+                (match_operand:SI 2 "arith_reg_operand")))
    (clobber (reg:SI T_REG))]
   "TARGET_SH1"
   "#"
                            (match_dup 1)))
              (clobber (reg:SI T_REG))])])
 
+(define_insn_and_split "*addc_r_t"
+  [(set (match_operand:SI 0 "arith_reg_dest")
+       (plus:SI (match_operand:SI 1 "arith_reg_operand")
+                (match_operand:SI 2 "t_reg_operand")))
+   (clobber (reg:SI T_REG))]
+  "TARGET_SH1"
+  "#"
+  "&& 1"
+  [(parallel [(set (match_dup 0)
+                  (plus:SI (plus:SI (match_dup 1) (const_int 0))
+                           (match_dup 2)))
+             (clobber (reg:SI T_REG))])])
+
 ;; Use shlr-addc to do 'reg + (reg & 1)'.
 (define_insn_and_split "*addc_r_lsb"
   [(set (match_operand:SI 0 "arith_reg_dest")
index a5d155c6e6fd2c5dfbaa82a50c83fd01cd39cf07..802f6545c7412a7fa6d97ea1fe6820c1453f09f1 100644 (file)
@@ -1,3 +1,8 @@
+2014-05-21  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/54236
+       * gcc.target/sh/pr54236-3.c: New.
+
 2014-05-21  Igor Zamyatin  <igor.zamyatin@intel.com>
 
        PR c++/60189
diff --git a/gcc/testsuite/gcc.target/sh/pr54236-3.c b/gcc/testsuite/gcc.target/sh/pr54236-3.c
new file mode 100644 (file)
index 0000000..fc0d111
--- /dev/null
@@ -0,0 +1,31 @@
+/* Tests to check the utilization of the addc and subc instructions.
+   If everything works as expected we won't see any movt instructions in
+   these cases.  */
+/* { dg-do compile }  */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
+/* { dg-final { scan-assembler-times "addc" 1 } } */
+/* { dg-final { scan-assembler-times "subc" 1 } } */
+/* { dg-final { scan-assembler-not "movt" } } */
+
+int
+test_000 (int* x, unsigned int c)
+{
+  /* 1x addc  */
+  int s = 0;
+  unsigned int i;
+  for (i = 0; i < c; ++i)
+    s += ! (x[i] & 0x3000);
+  return s;
+}
+
+int
+test_001 (int* x, unsigned int c)
+{
+  /* 1x subc  */
+  int s = 0;
+  unsigned int i;
+  for (i = 0; i < c; ++i)
+    s -= ! (x[i] & 0x3000);
+  return s;
+}