diff mbox

[SH,committed] Fix gcc.target/sh/pr54236-2.c failures

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

Commit Message

Oleg Endo May 19, 2015, 8:04 a.m. UTC
Hi,

Since a recent change to the tree optimizers
https://gcc.gnu.org/ml/gcc-patches/2015-05/msg00089.html
some related SH patterns stopped working.  The attached patch fixes
this.

Tested briefly with 'make all' and with
make -k check-gcc RUNTESTFLAGS="sh.exp=pr54236* --target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"

Committed as r223346.

Cheers,
Oleg

gcc/ChangeLog:
	PR target/54236
	* config/sh/sh.md (*round_int_even): New insn_and_split and
	accompanying new unnamed split.

gcc/testsuite/ChangeLog:
	PR target/54236
	* gcc.target/sh/pr54236-2.c: Adjust expected insn counts.
diff mbox

Patch

Index: gcc/testsuite/gcc.target/sh/pr54236-2.c
===================================================================
--- gcc/testsuite/gcc.target/sh/pr54236-2.c	(revision 223273)
+++ gcc/testsuite/gcc.target/sh/pr54236-2.c	(working copy)
@@ -4,12 +4,19 @@ 
 /* { dg-do compile }  */
 /* { dg-options "-O1" } */
 /* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
-/* { dg-final { scan-assembler-times "addc" 37 } } */
-/* { dg-final { scan-assembler-times "shlr" 23 } } */
+/* { dg-final { scan-assembler-times "addc" 36 } } */
+/* { dg-final { scan-assembler-times "shlr" 22 } } */
 /* { dg-final { scan-assembler-times "shll" 14 } } */
-/* { dg-final { scan-assembler-times "add\t" 12 } } */
+/* { dg-final { scan-assembler-times "add\tr" 12 } } */
 /* { dg-final { scan-assembler-not "movt" } } */
 
+/* { dg-final { scan-assembler-times "add\t#1" 1 } } */
+
+/* { dg-final { scan-assembler-times "mov\t#-2" 1 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "and\tr" 1 { target { ! sh2a } } } } */
+
+/* { dg-final { scan-assembler-times "bclr\t#0" 1 { target { sh2a } } } } */
+
 int
 test_000 (int a, int c, int b, int d)
 {
@@ -125,7 +132,8 @@ 
 int
 test_016 (int a, int b, int c, int d)
 {
-  // 1x shlr, 1x addc
+  // non-SH2A: 1x add #1, 1x mov #-2, 1x and
+  // SH2A: 1x add #1, 1x blcr #0
   return a + (a & 1);
 }
 
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	(revision 223274)
+++ gcc/config/sh/sh.md	(working copy)
@@ -1998,6 +1998,44 @@ 
   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
    (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))])
 
+
+;; The tree optimiziers canonicalize 
+;;    reg + (reg & 1)
+;; into
+;;    (reg + 1) & -2
+;;
+;; On SH2A an add-bclr sequence will be used to handle this.
+;; On non-SH2A re-emit the add-and sequence to improve register utilization.
+(define_insn_and_split "*round_int_even"
+  [(set (match_operand:SI 0 "arith_reg_dest")
+	(and:SI (plus:SI (match_operand:SI 1 "arith_reg_operand")
+			 (const_int 1))
+		(const_int -2)))]
+  "TARGET_SH1 && !TARGET_SH2A && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(set (match_dup 0) (const_int -2))
+   (set (match_dup 2) (plus:SI (match_dup 1) (const_int 1)))
+   (set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))]
+{
+  operands[2] = gen_reg_rtx (SImode);
+})
+
+;; If the *round_int_even pattern is combined with another plus,
+;; convert it into an addc pattern to emit an shlr-addc sequence.
+;; This split is taken by combine on non-SH2A and SH2A.
+(define_split
+  [(set (match_operand:SI 0 "arith_reg_dest")
+	(plus:SI (and:SI (plus:SI (match_operand:SI 1 "arith_reg_operand")
+				  (const_int 1))
+			 (const_int -2))
+		 (match_operand:SI 2 "arith_reg_operand")))]
+  "TARGET_SH1 && can_create_pseudo_p ()"
+  [(parallel [(set (match_dup 0)
+		   (plus:SI (plus:SI (match_dup 1) (match_dup 2))
+			    (and:SI (match_dup 1) (const_int 1))))
+	      (clobber (reg:SI T_REG))])])
+
 ;; Split 'reg + T' into 'reg + 0 + T' to utilize the addc insn.
 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
 ;; operation, as opposed to sequences such as