From: Oleg Endo Date: Mon, 30 Jul 2012 06:46:36 +0000 (+0000) Subject: re PR target/51244 ([SH] Inefficient conditional branch and code around T bit) X-Git-Tag: releases/gcc-4.8.0~4224 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=be8cbce15811f4d5ba02d7f3d8784b7b94b421d1;p=thirdparty%2Fgcc.git re PR target/51244 ([SH] Inefficient conditional branch and code around T bit) 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c734d9341f5c..4252084a2511 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-07-30 Oleg Endo + + 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 PR target/54089 diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 8edbb34e0598..88497c78eaae 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -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])); diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index b9be1290d607..6382238383d4 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -1584,15 +1584,6 @@ "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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c318d4513724..74af9650230c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-07-30 Oleg Endo + + PR target/51244 + * gcc.target/sh/pr51244-4.c: New. + 2012-07-27 Uros Bizjak * 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 index 000000000000..f3073780aeaf --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr51244-4.c @@ -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; +} +