]> 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>
Sun, 11 Mar 2012 13:18:08 +0000 (13:18 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Sun, 11 Mar 2012 13:18:08 +0000 (13:18 +0000)
PR target/51244
* config/sh/sh.md (movnegt): Expand into respective insns immediately.
Use movrt_negc instead of negc pattern for non-SH2A.
(*movnegt): Remove.
(*movrt_negc, *negnegt, *movtt, *movt_qi): New insns and splits.

PR target/51244
* gcc.target/sh/pr51244-1.c: Fix thinkos.

From-SVN: r185192

gcc/ChangeLog
gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/pr51244-1.c

index 8e5b4a9c742b16382db81cd22ca5c19158ec8c28..faafd809487cfde25769022b40be6150096d6543 100644 (file)
@@ -1,3 +1,11 @@
+2012-03-11  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/51244
+       * config/sh/sh.md (movnegt): Expand into respective insns immediately.
+       Use movrt_negc instead of negc pattern for non-SH2A.
+       (*movnegt): Remove.
+       (*movrt_negc, *negnegt, *movtt, *movt_qi): New insns and splits.
+
 2012-03-10  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/i386/i386.c (ix86_decompose_address): Disallow fs:(reg)
index eb1c85267f363722e3d3889a4332c750fdd8a2ef..528a120b17c9e628adb86cc3a2c191fdbafaa2e2 100644 (file)
@@ -9679,37 +9679,88 @@ mov.l\\t1f,r0\\n\\
 ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
 ;; becomes a one instruction operation.  Moreover, care must be taken that
 ;; the insn can still be combined with inverted compare and branch code
-;; around it.
-;; The expander will reserve the constant -1, the insn makes the whole thing
-;; combinable, the splitter finally emits the insn if it was not combined 
-;; away.
-;; Notice that when using the negc variant the T bit also gets inverted.
+;; around it.  On the other hand, if a function returns the complement of
+;; a previous comparison result in the T bit, the xor #1,r0 approach might
+;; lead to better code.
 
 (define_expand "movnegt"
-  [(set (match_dup 1) (const_int -1))
-   (parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
-                  (xor:SI (reg:SI T_REG) (const_int 1)))
-   (use (match_dup 1))])]
+  [(set (match_operand:SI 0 "arith_reg_dest" "")
+       (xor:SI (reg:SI T_REG) (const_int 1)))]
   ""
 {
-  operands[1] = gen_reg_rtx (SImode);
+  if (TARGET_SH2A)
+    emit_insn (gen_movrt (operands[0]));
+  else
+    {
+      rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
+      emit_insn (gen_movrt_negc (operands[0], val));
+    }
+  DONE;
 })
 
-(define_insn_and_split "*movnegt"
+(define_insn "movrt_negc"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
        (xor:SI (reg:SI T_REG) (const_int 1)))
+   (set (reg:SI T_REG) (const_int 1))
    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
   "TARGET_SH1"
+  "negc        %1,%0"
+  [(set_attr "type" "arith")])
+
+;; The *negnegt patterns help the combine pass to figure out how to fold 
+;; an explicit double T bit negation.
+(define_insn_and_split "*negnegt"
+  [(set (reg:SI T_REG)
+       (eq:SI (subreg:QI (xor:SI (reg:SI T_REG) (const_int 1)) 3)
+        (const_int 0)))]
+  "! TARGET_LITTLE_ENDIAN"
   "#"
-  "&& 1"
-  [(const_int 0)]
-{
-  if (TARGET_SH2A)
-    emit_insn (gen_movrt (operands[0]));
-  else
-    emit_insn (gen_negc (operands[0], operands[1]));
-  DONE;
-}
+  ""
+  [(const_int 0)])
+
+(define_insn_and_split "*negnegt"
+  [(set (reg:SI T_REG)
+       (eq:SI (subreg:QI (xor:SI (reg:SI T_REG) (const_int 1)) 0)
+        (const_int 0)))]
+  "TARGET_LITTLE_ENDIAN"
+  "#"
+  ""
+  [(const_int 0)])
+
+;; The *movtt patterns improve code at -O1.
+(define_insn_and_split "*movtt"
+  [(set (reg:SI T_REG)
+       (eq:SI (zero_extend:SI (subreg:QI (reg:SI T_REG) 3))
+        (const_int 1)))]
+  "! TARGET_LITTLE_ENDIAN"
+  "#"
+  ""
+  [(const_int 0)])
+
+(define_insn_and_split "*movtt"
+  [(set (reg:SI T_REG)
+       (eq:SI (zero_extend:SI (subreg:QI (reg:SI T_REG) 0))
+        (const_int 1)))]
+  "TARGET_LITTLE_ENDIAN"
+  "#"
+  ""
+  [(const_int 0)])
+
+;; The *movt_qi patterns help the combine pass convert a movrt_negc pattern
+;; into a movt Rn, xor #1 Rn pattern.  This can happen when e.g. a function
+;; returns the inverted T bit value.
+(define_insn "*movt_qi"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+       (zero_extend:SI (subreg:QI (reg:SI T_REG) 3)))]
+  "! TARGET_LITTLE_ENDIAN"
+  "movt        %0"
+  [(set_attr "type" "arith")])
+
+(define_insn "*movt_qi"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+       (zero_extend:SI (subreg:QI (reg:SI T_REG) 0)))]
+  "TARGET_LITTLE_ENDIAN"
+  "movt        %0"
   [(set_attr "type" "arith")])
 
 (define_expand "cstoresf4"
index 02342173db1be2e1bce898574e48e4cd2056e997..a9a31200b0304bfbd7d4b9734738fde0ae01be6d 100644 (file)
@@ -1,3 +1,8 @@
+2012-03-11  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/51244
+       * gcc.target/sh/pr51244-1.c: Fix thinkos.
+
 2012-03-10  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        PR target/52450
index 57af1040ae8a2fbf33ca2d5bf9c1eb7d3c957c22..34e1b0233266705c04e19945baa8ecf463819c45 100644 (file)
@@ -13,20 +13,20 @@ testfunc_00 (int a, int b, int c, int d)
 }
 
 int
-testfunc_01 (int a, char* p, int b, int c)
+testfunc_01 (int a, int b, int c, int d)
 {
-  return (a == b && a == c) ? b : c;
+  return (a == b || a == d) ? b : c;
 }
 
 int
-testfunc_02 (int a, char* p, int b, int c)
+testfunc_02 (int a, int b, int c, int d)
 {
-  return (a == b && a == c) ? b : c;
+  return (a == b && a == d) ? b : c;
 }
 
 int
-testfunc_03 (int a, char* p, int b, int c)
+testfunc_03 (int a, int b, int c, int d)
 {
-  return (a != b && a != c) ? b : c;
+  return (a != b && a != d) ? b : c;
 }