[SH] PR 39423 - Add support for SH2A movu.w insn

2012-08-21 Thread Oleg Endo
Hello,

This adds support for SH2A's movu.w insn for memory addressing cases as
described in the PR.
Tested on rev 190546 with
make -k check RUNTESTFLAGS=--target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}

and no new failures.
OK?

Cheers,
Oleg

ChangeLog:

PR target/39423
* config/sh/sh.md (*movhi_index_disp): Add support for SH2A 
movu.w insn.

testsuite/ChangeLog:

PR target/39423
* gcc.target/sh/pr39423-2.c: New.
Index: gcc/config/sh/sh.md
===
--- gcc/config/sh/sh.md	(revision 190459)
+++ gcc/config/sh/sh.md	(working copy)
@@ -5667,12 +5667,35 @@
(clobber (reg:SI T_REG))]
   TARGET_SH1
   #
-   1
-  [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
-	  (clobber (reg:SI T_REG))])
-   (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
+   can_create_pseudo_p ()
+  [(const_int 0)]
 {
-  operands[2] = gen_lowpart (HImode, operands[0]);
+  rtx mem = operands[1];
+  rtx plus0_rtx = XEXP (mem, 0);
+  rtx plus1_rtx = XEXP (plus0_rtx, 0);
+  rtx mult_rtx = XEXP (plus1_rtx, 0);
+
+  rtx op_1 = XEXP (mult_rtx, 0);
+  rtx op_2 = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1;
+  rtx op_3 = XEXP (plus1_rtx, 1);
+  rtx op_4 = XEXP (plus0_rtx, 1);
+  rtx op_5 = gen_reg_rtx (SImode);
+  rtx op_6 = gen_reg_rtx (SImode);
+  rtx op_7 = replace_equiv_address (mem, gen_rtx_PLUS (SImode, op_6, op_4));
+
+  emit_insn (gen_ashlsi3 (op_5, op_1, op_2));
+  emit_insn (gen_addsi3 (op_6, op_5, op_3));
+
+  /* On SH2A the movu.w insn can be used for zero extending loads.  */
+  if (TARGET_SH2A)
+emit_insn (gen_zero_extendhisi2 (operands[0], op_7));
+  else
+{
+  emit_insn (gen_extendhisi2 (operands[0], op_7));
+  emit_insn (gen_zero_extendhisi2 (operands[0],
+   gen_lowpart (HImode, operands[0])));
+}
+  DONE;
 })
 
 (define_insn_and_split *movsi_index_disp
Index: gcc/testsuite/gcc.target/sh/pr39423-2.c
===
--- gcc/testsuite/gcc.target/sh/pr39423-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/sh/pr39423-2.c	(revision 0)
@@ -0,0 +1,14 @@
+/* Check that displacement addressing is used for indexed addresses with a
+   small offset, instead of re-calculating the index and that the movu.w
+   instruction is used on SH2A.  */
+/* { dg-do compile { target sh*-*-* } } */
+/* { dg-options -O2 } */
+/* { dg-skip-if  { sh*-*-* } { * } { -m2a* } } */
+/* { dg-final { scan-assembler-not add\t#1 } } */
+/* { dg-final { scan-assembler movu.w } } */
+
+int
+test_00 (unsigned short tab[], int index)
+{
+  return tab[index + 1];
+}


Re: [SH] PR 39423 - Add support for SH2A movu.w insn

2012-08-21 Thread Kaz Kojima
Oleg Endo oleg.e...@t-online.de wrote:
 This adds support for SH2A's movu.w insn for memory addressing cases as
 described in the PR.
 Tested on rev 190546 with
 make -k check RUNTESTFLAGS=--target_board=sh-sim
 \{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}
 
 and no new failures.
 OK?

OK.

Regards,
kaz


[SH] PR 39423

2012-08-16 Thread Oleg Endo
Hello,

This fixes the issue mentioned in the PR's comment #29.
Tested on rev 190396 with
make -k check RUNTESTFLAGS=--target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}

and no new failures.
OK?

Cheers,
Oleg

ChangeLog:

PR target/39423
* config/sh/sh.md (*movsi_index_disp, *movhi_index_disp): 
Handle potential T_REG clobber.  Convert zero extending split 
to insn_and_split.
Index: gcc/config/sh/sh.md
===
--- gcc/config/sh/sh.md	(revision 190396)
+++ gcc/config/sh/sh.md	(working copy)
@@ -5455,16 +5455,22 @@
 ;;	mov.l	@(4,r5),r0
 ;;
 ;; See also PR 39423.
+;; Notice that these patterns have a T_REG clobber, because the shift
+;; sequence that will be split out might clobber the T_REG.  Ideally, the
+;; clobber would be added conditionally, depending on the result of
+;; sh_ashlsi_clobbers_t_reg_p.  When splitting out the shifts we must go
+;; through the ashlsi3 expander in order to get the right shift insn --
+;; a T_REG clobbering or non-clobbering shift sequence or dynamic shift.
 ;; 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)
-	(match_operand:SI 1 mem_index_disp_operand m))]
+	(match_operand:SI 1 mem_index_disp_operand m))
+   (clobber (reg:SI T_REG))]
   TARGET_SH1
   #
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 6) (plus:SI (match_dup 5) (match_dup 3)))
(set (match_dup 0) (match_dup 7))]
 {
   rtx mem = operands[1];
@@ -5481,16 +5487,18 @@
   operands[7] =
 replace_equiv_address (mem,
 			   gen_rtx_PLUS (SImode, operands[6], operands[4]));
+
+  emit_insn (gen_ashlsi3 (operands[5], operands[1], operands[2]));
 })
 
 (define_insn_and_split *movhi_index_disp
   [(set (match_operand:SI 0 arith_reg_dest =r)
-	(sign_extend:SI (match_operand:HI 1 mem_index_disp_operand m)))]
+	(sign_extend:SI (match_operand:HI 1 mem_index_disp_operand m)))
+   (clobber (reg:SI T_REG))]
   TARGET_SH1
   #
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 6) (plus:SI (match_dup 5) (match_dup 3)))
(set (match_dup 0) (sign_extend:SI (match_dup 7)))]
 {
   rtx mem = operands[1];
@@ -5507,13 +5515,19 @@
   operands[7] =
 replace_equiv_address (mem,
 			   gen_rtx_PLUS (SImode, operands[6], operands[4]));
+
+  emit_insn (gen_ashlsi3 (operands[5], operands[1], operands[2]));
 })
 
-(define_split
+(define_insn_and_split *movhi_index_disp
   [(set (match_operand:SI 0 arith_reg_dest)
-	(zero_extend:SI (match_operand:HI 1 mem_index_disp_operand)))]
+	(zero_extend:SI (match_operand:HI 1 mem_index_disp_operand)))
+   (clobber (reg:SI T_REG))]
   TARGET_SH1
-  [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
+  #
+   1
+  [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
+	  (clobber (reg:SI T_REG))])
(set (match_dup 0) (zero_extend:SI (match_dup 2)))]
 {
   operands[2] = gen_lowpart (HImode, operands[0]);
@@ -5521,12 +5535,12 @@
 
 (define_insn_and_split *movsi_index_disp
   [(set (match_operand:SI 0 mem_index_disp_operand =m)
-	(match_operand:SI 1 arith_reg_operand r))]
+	(match_operand:SI 1 arith_reg_operand r))
+   (clobber (reg:SI T_REG))]
   TARGET_SH1
   #
can_create_pseudo_p ()
-  [(set (match_dup 5) (ashift:SI (match_dup 0) (match_dup 2)))
-   (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
+ [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
(set (match_dup 7) (match_dup 1))]
 {
   rtx mem = operands[0];
@@ -5543,16 +5557,18 @@
   operands[7] =
 replace_equiv_address (mem,
 			   gen_rtx_PLUS (SImode, operands[6], operands[4]));
+
+  emit_insn (gen_ashlsi3 (operands[5], operands[0], operands[2]));
 })
 
 (define_insn_and_split *movsi_index_disp
   [(set (match_operand:HI 0 mem_index_disp_operand =m)
-	(match_operand:HI 1 arith_reg_operand r))]
+	(match_operand:HI 1 arith_reg_operand r))
+   (clobber (reg:SI T_REG))]
   TARGET_SH1
   #
can_create_pseudo_p ()
-  [(set (match_dup 5) (ashift:SI (match_dup 0) (match_dup 2)))
-   (set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
+  [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
(set (match_dup 7) (match_dup 1))]
 {
   rtx mem = operands[0];
@@ -5569,6 +5585,8 @@
   operands[7] =
 replace_equiv_address (mem,
 			   gen_rtx_PLUS (SImode, operands[6], operands[4]));
+
+  emit_insn (gen_ashlsi3 (operands[5], operands[0], operands[2]));
 })
 
 ;; Define additional pop for SH1 and SH2 so it does not get 


Re: [SH] PR 39423

2012-08-16 Thread Kaz Kojima
Oleg Endo oleg.e...@t-online.de wrote:
 This fixes the issue mentioned in the PR's comment #29.
 Tested on rev 190396 with
 make -k check RUNTESTFLAGS=--target_board=sh-sim
 \{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}
 
 and no new failures.
 OK?

OK.

Regards,
kaz


[SH] PR 39423 - Fix ICEs, add more tests

2012-08-12 Thread Oleg Endo
Hello,

This patch fixes ICEs such as reported in the PR due to wrong predicate
matching and adds test cases for those.
Tested on rev 190273 with
make -k check RUNTESTFLAGS=--target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}

and no new failures.
OK?

Cheers,
Oleg

ChangeLog:

PR target/39423
* config/sh/predicates.md (mem_index_disp_operand): Check for 
arith_reg_operand instead of REG_P.

testsuite/ChangeLog:

PR target/39423
* gcc.c-torture/compile/pr39423-1.c: New.
* gcc.c-torture/compile/pr39423-2.c: New.
Index: gcc/testsuite/gcc.c-torture/compile/pr39423-2.c
===
--- gcc/testsuite/gcc.c-torture/compile/pr39423-2.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr39423-2.c	(revision 0)
@@ -0,0 +1,57 @@
+/* PR target/39423 */
+
+typedef unsigned short uint16_t;
+
+typedef struct
+{
+  short x, y;
+} P;
+
+typedef struct
+{
+  uint16_t w, h;
+} D;
+
+typedef struct
+{
+  P p;
+  D s;
+} A;
+
+typedef struct
+{
+  uint16_t f;
+} W;
+
+typedef struct
+{
+  void* w;
+  D s;
+} T;
+
+extern void* foo00 (void*, void*);
+
+void foo01 (W* w)
+{
+  void* it;
+  uint16_t c, i;
+  T* cl;
+  T* rs;
+  T* t;
+  uint16_t rh = 0;
+  uint16_t v = !(w-f  0x8000);
+  A a = { };
+
+  for (c = 0, it = foo00 (w, 0); it; it = foo00 (w, it), c++);
+
+  for (it = foo00 (w, 0), i = 0; i = c; it = foo00 (w, it), i++, cl++)
+{
+  if (i)
+ 	for (t = rs; t  cl; t++)
+	  *((uint16_t*)t-s + ((!v) ? 1 : 0)) = rh;
+
+  rh = (rh  ((*((uint16_t*)a.s + ((!v) ? 1 : 0)
+	   ? rh
+	   : ((*((uint16_t*)a.s + ((!v) ? 1 : 0; 
+}
+}
Index: gcc/testsuite/gcc.c-torture/compile/pr39423-1.c
===
--- gcc/testsuite/gcc.c-torture/compile/pr39423-1.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr39423-1.c	(revision 0)
@@ -0,0 +1,22 @@
+/* PR target/39423 */
+
+int
+foo (const char *name, int nmlen, char *flags)
+{
+  const char *nonspc;
+  int len, n, lfn;
+  int needlfn[2], dotspc[2];
+  unsigned char locale[2];
+  for (nonspc = name[nmlen - 1]; nonspc = name  *nonspc == ' '; ++n)
+{
+  if (!nmlen)
+	{
+	  needlfn[name = nonspc] = !0, dotspc[n != 0] =
+	locale[0], --n, name += len, nmlen -= len;
+	}
+}
+  if (!lfn  ((dotspc[0] == ' '  !(len  0x0010)) || dotspc[0] == '.'))
+return 22;
+  if (!(needlfn[0] || needlfn[1]))
+*flags |= 0x02;
+}
Index: gcc/config/sh/predicates.md
===
--- gcc/config/sh/predicates.md	(revision 190273)
+++ gcc/config/sh/predicates.md	(working copy)
@@ -521,14 +521,17 @@
   plus1_rtx = XEXP (plus0_rtx, 0);
   if (GET_CODE (plus1_rtx) != PLUS)
 return 0;
+  if (! arith_reg_operand (XEXP (plus1_rtx, 1), GET_MODE (XEXP (plus1_rtx, 1
+return 0;
 
   mult_rtx = XEXP (plus1_rtx, 0);
   if (GET_CODE (mult_rtx) != MULT)
 return 0;
- 
-  return REG_P (XEXP (mult_rtx, 0))  CONST_INT_P (XEXP (mult_rtx, 1))
-	  exact_log2 (INTVAL (XEXP (mult_rtx, 1)))  0
-	  REG_P (XEXP (plus1_rtx, 1))
+  if (! arith_reg_operand (XEXP (mult_rtx, 0), GET_MODE (XEXP (mult_rtx, 0)))
+  || ! CONST_INT_P (XEXP (mult_rtx, 1)))
+return 0;
+
+  return exact_log2 (INTVAL (XEXP (mult_rtx, 1)))  0
 	  sh_legitimate_index_p (mode, XEXP (plus0_rtx, 1), TARGET_SH2A, true);
 })
 


Re: [SH] PR 39423 - Fix ICEs, add more tests

2012-08-12 Thread Kaz Kojima
Oleg Endo oleg.e...@t-online.de wrote:
 This patch fixes ICEs such as reported in the PR due to wrong predicate
 matching and adds test cases for those.
 Tested on rev 190273 with
 make -k check RUNTESTFLAGS=--target_board=sh-sim
 \{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}
 
 and no new failures.
 OK?

OK.

Regards,
kaz


Re: [SH] PR 39423

2012-08-09 Thread Kaz Kojima
Oleg Endo oleg.e...@t-online.de wrote:
 How about the attached patch?
 Is that way of dealing with the mems OK?
 What could be a possible test case for the alias info issue?
 
 Tested on rev 190151 with
 make -k check RUNTESTFLAGS=--target_board=sh-sim
 \{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}
 
 and no new failures.

This patch is OK.

Regards,
kaz


Re: [SH] PR 39423

2012-08-08 Thread Oleg Endo
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))]

How about the attached patch?
Is that way of dealing with the mems OK?
What could be a possible test case for the alias info issue?

Tested on rev 190151 with
make -k check RUNTESTFLAGS=--target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}

and no new failures.

Cheers,
Oleg

ChangeLog:
PR target/39423
* config/sh/predicates.md (mem_index_disp_operand): New 
predicate.
* config/sh/sh.md (*movsi_index_disp): Rewrite insns to use the 
new mem_index_disp_operand predicate.

testsuite/ChangeLog:
PR target/39423
* gcc.target/sh/pr39423-1.c: New.
Index: gcc/config/sh/sh.md
===
--- gcc/config/sh/sh.md	(revision 190151)
+++ gcc/config/sh/sh.md	(working copy)
@@ -5119,114 +5119,116 @@
 ;; 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
+	(match_operand:SI 1 mem_index_disp_operand m))]
+  TARGET_SH1
   #
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]
+   (set (match_dup 0) (match_dup 7))]
 {
+  rtx mem = operands[1];
+  rtx plus0_rtx = XEXP (mem, 0);
+  rtx plus1_rtx = XEXP (plus0_rtx, 0);
+  rtx mult_rtx = XEXP (plus1_rtx, 0);
+
+  operands[1] = XEXP (mult_rtx, 0);
+  operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1;
+  operands[3] = XEXP (plus1_rtx, 1);
+  operands[4] = XEXP (plus0_rtx, 1);
   operands[5] = gen_reg_rtx (SImode);
   operands[6] = gen_reg_rtx (SImode);
-  operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
+  operands[7] =
+replace_equiv_address (mem,
+			   gen_rtx_PLUS (SImode, operands[6], operands[4]));
 })
 
 (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
+	(sign_extend:SI (match_operand:HI 1 mem_index_disp_operand m)))]
+  TARGET_SH1
   #
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)]
+   (set (match_dup 0) (sign_extend:SI (match_dup 7)))]
 {
+  rtx mem = operands[1];
+  rtx plus0_rtx = XEXP (mem, 0);
+  rtx plus1_rtx = XEXP (plus0_rtx, 0);
+  rtx mult_rtx = XEXP (plus1_rtx, 0);
+
+  operands[1] = XEXP (mult_rtx, 0);
+  operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1;
+  operands[3] = XEXP (plus1_rtx, 1);
+  operands[4] = XEXP (plus0_rtx, 1);
   operands[5] = gen_reg_rtx (SImode);
   operands[6] = gen_reg_rtx (SImode);
-  operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
+  operands[7] =
+replace_equiv_address (mem,
+			   gen_rtx_PLUS (SImode, operands[6], operands[4]));
 })
 
-(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) 

Re: [SH] PR 39423

2012-08-08 Thread Richard Henderson
On 08/08/2012 03:12 PM, Oleg Endo wrote:
 How about the attached patch?
 Is that way of dealing with the mems OK?
 What could be a possible test case for the alias info issue?

That looks like the right sort of thing.

A test case would have to be for a missed-optimization,
where we failed to schedule one load before another.
It could be very hard to generate one intentionally...


r~


Re: [SH] PR 39423

2012-07-30 Thread Richard Henderson
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~


Re: [SH] PR 39423

2012-07-30 Thread Oleg Endo
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 



[SH] PR 39423

2012-07-29 Thread Oleg Endo
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.

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 

Re: [SH] PR 39423

2012-07-29 Thread Kaz Kojima
Oleg Endo oleg.e...@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