diff mbox

[SH] PR 51244 - Improve conditional branches

Message ID 1331195493.1876.14.camel@yam-132-YW-E178-FTW
State New
Headers show

Commit Message

Oleg Endo March 8, 2012, 8:31 a.m. UTC
On Tue, 2012-03-06 at 08:13 +0900, Kaz Kojima wrote:
> > Oleg Endo <oleg.endo@t-online.de> wrote:
> >> The attached patch is the same as the last one proposed in the PR.
> >> Tested against rev 184877 with
> >> 
> >> make -k check RUNTESTFLAGS="--target_board=sh-sim
> >> \{-m2/-ml,-m2/-mb,-m2a-single/-mb,
> >> -m4-single/-ml,-m4-single/-mb,
> >> -m4a-single/-ml,-m4a-single/-mb}"
> >> 
> >> and no new failures.
> >> OK?
> > 
> > OK.
> 
> I've tested your latest patch on sh4-unknown-linux-gnu with trunk
> revision 184872.  It looks that some new failures are poping up:
> 
> New tests that FAIL:
> 
> 22_locale/ctype/is/char/3.cc execution test
> 27_io/basic_filebuf/underflow/wchar_t/9178.cc execution test
> gfortran.dg/widechar_intrinsics_6.f90  -Os  execution test
> 
> Pehaps failures might be ones you've suggested in #10 in
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51244
> 

This is the patch for the patch, as attached in the PR.
Tested against rev 184966 as before and no changes in the test results
for me (i.e. no new failures).

ChangeLog:

	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.

testsuite/ChangeLog:

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

Patch

Index: gcc/testsuite/gcc.target/sh/pr51244-1.c
===================================================================
--- gcc/testsuite/gcc.target/sh/pr51244-1.c	(revision 184966)
+++ gcc/testsuite/gcc.target/sh/pr51244-1.c	(working copy)
@@ -13,20 +13,20 @@ 
 }
 
 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;
 }
 
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	(revision 184966)
+++ gcc/config/sh/sh.md	(working copy)
@@ -9679,39 +9679,90 @@ 
 ;; 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) (xor:SI (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"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(match_operator:SI 1 "sh_float_comparison_operator"