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);
 })
 

Reply via email to