]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/51244 ([SH] Inefficient conditional branch and code around T bit)
authorOleg Endo <olegendo@gcc.gnu.org>
Mon, 30 Jul 2012 06:46:36 +0000 (06:46 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Mon, 30 Jul 2012 06:46:36 +0000 (06:46 +0000)
PR target/51244
* config/sh/sh.md (mov_neg_si_t): Move to Scc instructions section.
Use t_reg_operand predicate.  Add split for negated case.
(ashrsi2_31): Pass get_t_reg_rtx to gen_mov_neg_si_t.
* config/sh/sh.c (expand_ashiftrt): Likewise.

PR target/51244
* gcc.target/sh/pr51244-4.c: New.

From-SVN: r189953

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

index c734d9341f5cd7db115c2a53a38f6c7938dc3f18..4252084a25113d2542515007bb7c6f7ed6054dcf 100644 (file)
@@ -1,3 +1,11 @@
+2012-07-30  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/51244
+       * config/sh/sh.md (mov_neg_si_t): Move to Scc instructions section.
+       Use t_reg_operand predicate.  Add split for negated case.
+       (ashrsi2_31): Pass get_t_reg_rtx to gen_mov_neg_si_t.
+       * config/sh/sh.c (expand_ashiftrt): Likewise.
+
 2012-07-30  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/54089
index 8edbb34e05987759aa1e68fff9e5eaf8fbf9bc9e..88497c78eaae687dde07180b21b257abd08dfa7b 100644 (file)
@@ -3481,7 +3481,7 @@ expand_ashiftrt (rtx *operands)
        {
          emit_insn (gen_cmpgtsi_t (force_reg (SImode, CONST0_RTX (SImode)),
                                    operands[1]));
-         emit_insn (gen_mov_neg_si_t (operands[0]));
+         emit_insn (gen_mov_neg_si_t (operands[0], get_t_reg_rtx ()));
          return true;
        }
       emit_insn (gen_ashrsi2_31 (operands[0], operands[1]));
index b9be1290d607a341431019d94845eba39c9a8a6f..6382238383d4085ef90fcdabc4b3b6b140fa381c 100644 (file)
   "subc        %2,%0"
   [(set_attr "type" "arith")])
 
-;; life_analysis thinks rn is live before subc rn,rn, so make a special
-;; pattern for this case.  This helps multimedia applications that compute
-;; the sum of absolute differences.
-(define_insn "mov_neg_si_t"
-  [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
-  "TARGET_SH1"
-  "subc        %0,%0"
-  [(set_attr "type" "arith")])
-
 (define_insn "*subsi3_internal"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
        (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
@@ -3802,7 +3793,7 @@ label:
   [(const_int 0)]
 {
   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
-  emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
+  emit_insn (gen_mov_neg_si_t (operands[0], get_t_reg_rtx ()));
   DONE;
 })
 
@@ -9709,6 +9700,25 @@ label:
   ""
   [(const_int 0)])
 
+;; Store T bit as all zeros or ones in a reg.
+(define_insn "mov_neg_si_t"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+       (neg:SI (match_operand 1 "t_reg_operand" "")))]
+  "TARGET_SH1"
+  "subc        %0,%0"
+  [(set_attr "type" "arith")])
+
+;; Store negated T bit as all zeros or ones in a reg.
+;; Use the following sequence:
+;;     subc    Rn,Rn   ! Rn = Rn - Rn - T; T = T
+;;     not     Rn,Rn   ! Rn = 0 - Rn
+(define_split
+  [(set (match_operand:SI 0 "arith_reg_dest" "")
+       (neg:SI (match_operand 1 "negt_reg_operand" "")))]
+  "TARGET_SH1"
+  [(set (match_dup 0) (neg:SI (reg:SI T_REG)))
+   (set (match_dup 0) (not:SI (match_dup 0)))])
+
 ;; The *movtt pattern eliminates redundant T bit to T bit moves / tests.
 (define_insn_and_split "*movtt"
   [(set (reg:SI T_REG)
index c318d4513724ebfec139347934387f8b362b1ba0..74af9650230cb234a51c7e0404f5f86f12861acf 100644 (file)
@@ -1,3 +1,8 @@
+2012-07-30  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/51244
+       * gcc.target/sh/pr51244-4.c: New.
+
 2012-07-27  Uros Bizjak  <ubizjak@gmail.com>
 
        * gfortran.dg/bind_c_array_params_2.f90: Add "-mno-explicit-relocs"
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-4.c b/gcc/testsuite/gcc.target/sh/pr51244-4.c
new file mode 100644 (file)
index 0000000..f307378
--- /dev/null
@@ -0,0 +1,19 @@
+/* Check that storing the (negated) T bit as all ones or zeros in a reg
+   uses the subc instruction.  On SH2A a sequence with the movrt instruction
+   is also OK instead of subc.  */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1 -mbranch-cost=2" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
+/* { dg-final { scan-assembler-not "movt|tst|negc" } } */
+/* { dg-final { scan-assembler "subc|movrt|neg|not" } } */
+
+int test_00 (int x, int y)
+{
+  return x != y ? -1 : 0;
+}
+
+int test_01 (int x, int y)
+{
+  return x == y ? -1 : 0;
+}
+