diff mbox

[SH] PR 51244 - Improve conditional branches

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

Commit Message

Oleg Endo March 11, 2012, 11:52 a.m. UTC
On Thu, 2012-03-08 at 09:31 +0100, Oleg Endo wrote:

> 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).

This one had a bug, as discussed in the PR.
I've tested the attached latest version of the patch (same as in the PR)
against rev 185160 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}"

once more and confirmed that there are no new failures.  The new failure
'21_strings/basic_string/cons/char/6.cc' mentioned in the PR is failing
due to the test program allocating too much memory for the simulator.
It aborts with a 'heap and stack collision'.  Chaning the number of test
iterations in the test case from '13' to '12' makes it pass again.

OK to commit the patch?

Cheers,
Oleg

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.

Comments

Kaz Kojima March 11, 2012, 12:32 p.m. UTC | #1
Oleg Endo <oleg.endo@t-online.de> wrote:
> This one had a bug, as discussed in the PR.
> I've tested the attached latest version of the patch (same as in the PR)
> against rev 185160 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}"
> 
> once more and confirmed that there are no new failures.  The new failure
> '21_strings/basic_string/cons/char/6.cc' mentioned in the PR is failing
> due to the test program allocating too much memory for the simulator.
> It aborts with a 'heap and stack collision'.  Chaning the number of test
> iterations in the test case from '13' to '12' makes it pass again.
> 
> OK to commit the patch?

OK.

Regards,
	kaz
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) (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"