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