diff mbox

[SH] PR 39423

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

Commit Message

Oleg Endo July 29, 2012, 10:56 p.m. UTC
Hello,

The attached patch adds the combine patterns as discussed in the PR.
Tested on rev 189916 with
make -k check RUNTESTFLAGS="--target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m2a-single/-mb,-m4/-ml,-m4/-mb,
-m4-single/-ml,-m4-single/-mb,-m4a-single/-ml,-m4a-single/-mb}"

and no new failures.
Test cases will follow in a separate patch.

Cheers,
Oleg

ChangeLog
	PR target/39423
	* config/gcc/sh/sh.md (*movsi_index_disp, *movhi_index_disp):
	New insns.

Comments

Kaz Kojima July 30, 2012, 3:14 a.m. UTC | #1
Oleg Endo <oleg.endo@t-online.de> wrote:
> The attached patch adds the combine patterns as discussed in the PR.
> Tested on rev 189916 with
> make -k check RUNTESTFLAGS="--target_board=sh-sim
> \{-m2/-ml,-m2/-mb,-m2a/-mb,-m2a-single/-mb,-m4/-ml,-m4/-mb,
> -m4-single/-ml,-m4-single/-mb,-m4a-single/-ml,-m4a-single/-mb}"
> 
> and no new failures.
> Test cases will follow in a separate patch.

OK.

Regards,
	kaz
Richard Henderson July 30, 2012, 3:28 p.m. UTC | #2
On 2012-07-29 15:56, Oleg Endo wrote:
> +  "&& can_create_pseudo_p ()"
> +  [(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
> +   (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
> +   (set (match_dup 0) (mem:SI (plus:SI (match_dup 6) (match_dup 4))))]

Don't create new mems like this -- you've lost alias info.
You need to use replace_equiv_address or something on the
original memory.  Which means you have to actually capture
the memory operand somehow.

Better to use a custom predicate to match these memories with
these complex addresses, rather than list them out each time:

  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
	(match_operand:SI 1 "mem_index_disp_operand" "m"))]


r~
Oleg Endo July 30, 2012, 7:44 p.m. UTC | #3
On Mon, 2012-07-30 at 08:28 -0700, Richard Henderson wrote:
> On 2012-07-29 15:56, Oleg Endo wrote:
> > +  "&& can_create_pseudo_p ()"
> > +  [(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
> > +   (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
> > +   (set (match_dup 0) (mem:SI (plus:SI (match_dup 6) (match_dup 4))))]
> 
> Don't create new mems like this -- you've lost alias info.
> You need to use replace_equiv_address or something on the
> original memory.  Which means you have to actually capture
> the memory operand somehow.
> 
> Better to use a custom predicate to match these memories with
> these complex addresses, rather than list them out each time:
> 
>   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
> 	(match_operand:SI 1 "mem_index_disp_operand" "m"))]
> 

Thanks!  I'll fix it in another patch.

Cheers,
Oleg
diff mbox

Patch

Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	(revision 189916)
+++ gcc/config/sh/sh.md	(working copy)
@@ -5107,6 +5107,132 @@ 
   "TARGET_SH1"
   "sett")
 
+
+;; Use the combine pass to transform sequences such as
+;;	mov	r5,r0
+;;	add	#1,r0
+;;	shll2	r0
+;;	mov.l	@(r0,r4),r0
+;; into
+;;	shll2	r5
+;;	add	r4,r5
+;;	mov.l	@(4,r5),r0
+;;
+;; See also PR 39423.
+;; FIXME: Fold copy pasted patterns somehow.
+;; FIXME: Combine never tries this kind of patterns for DImode.
+(define_insn_and_split "*movsi_index_disp"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+	(mem:SI
+	  (plus:SI
+	    (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
+			      (match_operand:SI 2 "const_int_operand"))
+		     (match_operand:SI 3 "arith_reg_operand" "r"))
+	    (match_operand:SI 4 "const_int_operand"))))]
+  "TARGET_SH1 && sh_legitimate_index_p (SImode, operands[4], TARGET_SH2A, true)
+   && exact_log2 (INTVAL (operands[2])) > 0"
+  "#"
+  "&& can_create_pseudo_p ()"
+  [(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
+   (set (match_dup 0) (mem:SI (plus:SI (match_dup 6) (match_dup 4))))]
+{
+  operands[5] = gen_reg_rtx (SImode);
+  operands[6] = gen_reg_rtx (SImode);
+  operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
+})
+
+(define_insn_and_split "*movhi_index_disp"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+	(sign_extend:SI
+	  (mem:HI
+	    (plus:SI
+	      (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
+				(match_operand:SI 2 "const_int_operand"))
+		       (match_operand:SI 3 "arith_reg_operand" "r"))
+	      (match_operand:SI 4 "const_int_operand")))))]
+  "TARGET_SH1 && sh_legitimate_index_p (HImode, operands[4], TARGET_SH2A, true)
+   && exact_log2 (INTVAL (operands[2])) > 0"
+  "#"
+  "&& can_create_pseudo_p ()"
+  [(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
+   (set (match_dup 0)
+	(sign_extend:SI (mem:HI (plus:SI (match_dup 6) (match_dup 4)))))]
+{
+  operands[5] = gen_reg_rtx (SImode);
+  operands[6] = gen_reg_rtx (SImode);
+  operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
+})
+
+(define_insn_and_split "*movhi_index_disp"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+	(zero_extend:SI
+	  (mem:HI
+	    (plus:SI
+	      (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
+				(match_operand:SI 2 "const_int_operand"))
+		       (match_operand:SI 3 "arith_reg_operand" "r"))
+	      (match_operand:SI 4 "const_int_operand")))))]
+  "TARGET_SH1 && sh_legitimate_index_p (HImode, operands[4], TARGET_SH2A, true)
+   && exact_log2 (INTVAL (operands[2])) > 0"
+  "#"
+  "&& can_create_pseudo_p ()"
+  [(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
+   (set (match_dup 7)
+	(sign_extend:SI (mem:HI (plus:SI (match_dup 6) (match_dup 4)))))
+   (set (match_dup 0) (zero_extend:SI (match_dup 8)))]
+{
+  operands[5] = gen_reg_rtx (SImode);
+  operands[6] = gen_reg_rtx (SImode);
+  operands[7] = gen_reg_rtx (SImode);
+  operands[8] = gen_lowpart (HImode, operands[7]);
+  operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
+})
+
+(define_insn_and_split "*movsi_index_disp"
+  [(set (mem:SI
+	  (plus:SI
+	    (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
+			      (match_operand:SI 2 "const_int_operand"))
+		     (match_operand:SI 3 "arith_reg_operand" "r"))
+	  (match_operand:SI 4 "const_int_operand")))
+	(match_operand:SI 0 "arith_reg_operand" "r"))]
+  "TARGET_SH1 && sh_legitimate_index_p (SImode, operands[4], TARGET_SH2A, true)
+   && exact_log2 (INTVAL (operands[2])) > 0"
+  "#"
+  "&& can_create_pseudo_p ()"
+  [(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
+   (set (mem:SI (plus:SI (match_dup 6) (match_dup 4))) (match_dup 0))]
+{
+  operands[5] = gen_reg_rtx (SImode);
+  operands[6] = gen_reg_rtx (SImode);
+  operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
+})
+
+(define_insn_and_split "*movhi_index_disp"
+  [(set (mem:HI
+	  (plus:SI
+	    (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand" "r")
+			      (match_operand:SI 2 "const_int_operand"))
+		     (match_operand:SI 3 "arith_reg_operand" "r"))
+	  (match_operand:SI 4 "const_int_operand")))
+	(match_operand:HI 0 "arith_reg_operand" "r"))]
+  "TARGET_SH1 && sh_legitimate_index_p (HImode, operands[4], TARGET_SH2A, true)
+   && exact_log2 (INTVAL (operands[2])) > 0"
+  "#"
+  "&& can_create_pseudo_p ()"
+  [(set (match_dup 5) (ashift:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
+   (set (mem:HI (plus:SI (match_dup 6) (match_dup 4))) (match_dup 0))]
+{
+  operands[5] = gen_reg_rtx (SImode);
+  operands[6] = gen_reg_rtx (SImode);
+  operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
+})
+
 ;; Define additional pop for SH1 and SH2 so it does not get 
 ;; placed in the delay slot.
 (define_insn "*movsi_pop"