diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2012-08-12 13:23:20 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2012-08-12 13:23:20 +0000 |
commit | 05852a5f5ad46ba070953c73b6b42c29c49f5516 (patch) | |
tree | 464f47b1cbd1d97b2f363e834136c1092fdafe7b /gcc | |
parent | 58341a42945fd052a5d27ef932a41038f11e3398 (diff) | |
download | gcc-05852a5f5ad46ba070953c73b6b42c29c49f5516.zip gcc-05852a5f5ad46ba070953c73b6b42c29c49f5516.tar.gz gcc-05852a5f5ad46ba070953c73b6b42c29c49f5516.tar.bz2 |
re PR target/39423 ([SH] performance regression: lost mov @(disp,Rn))
PR target/39423
* config/sh/predicates.md (mem_index_disp_operand): Check for
arith_reg_operand instead of REG_P.
PR target/39423
* gcc.c-torture/compile/pr39423-1.c: New.
* gcc.c-torture/compile/pr39423-2.c: New.
From-SVN: r190326
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/sh/predicates.md | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr39423-1.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr39423-2.c | 57 |
5 files changed, 98 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0aabdc3..0fd7f72 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-08-12 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/39423 + * config/sh/predicates.md (mem_index_disp_operand): Check for + arith_reg_operand instead of REG_P. + 2012-08-11 Bernd Schmidt <bernds@codesourcery.com> * reload1.c (replaced_subreg, gen_reload): Add diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md index 209ff29..7defa77 100644 --- a/gcc/config/sh/predicates.md +++ b/gcc/config/sh/predicates.md @@ -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); }) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a11888b..f9c8ff4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-08-12 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/39423 + * gcc.c-torture/compile/pr39423-1.c: New. + * gcc.c-torture/compile/pr39423-2.c: New. + 2012-08-12 Tobias Burnus <burnus@net-b.de> PR fortran/54221 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr39423-1.c b/gcc/testsuite/gcc.c-torture/compile/pr39423-1.c new file mode 100644 index 0000000..34ebb66 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr39423-1.c @@ -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; +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr39423-2.c b/gcc/testsuite/gcc.c-torture/compile/pr39423-2.c new file mode 100644 index 0000000..5307846 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr39423-2.c @@ -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)))); + } +} |