From a700b5f073c45564f513ff035b2c0d5fb0edfaa0 Mon Sep 17 00:00:00 2001 From: Kaz Kojima Date: Thu, 2 Jun 2011 22:26:42 +0000 Subject: [PATCH] predicates.md (general_movsrc_operand): Return 0 for memory and memory subreg of which address is an invalid indexed... * config/sh/predicates.md (general_movsrc_operand): Return 0 for memory and memory subreg of which address is an invalid indexed address for QI and HImode. (general_movdst_operand): Likewise. * gcc.c-torture/compile/pr49163.c: New. From-SVN: r174586 --- gcc/ChangeLog | 8 +++++ gcc/config/sh/predicates.md | 24 +++++++++++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.c-torture/compile/pr49163.c | 35 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr49163.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4533f582d9b..a6fd4de01bc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2011-06-02 Kaz Kojima + + PR target/49163 + * config/sh/predicates.md (general_movsrc_operand): Return 0 + for memory and memory subreg of which address is an invalid + indexed address for QI and HImode. + (general_movdst_operand): Likewise. + 2011-06-02 Eric Botcazou * cse.c (cse_find_path): Refine change to exclude EDGE_ABNORMAL_CALL diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md index b6508b70d68..20354588d99 100644 --- a/gcc/config/sh/predicates.md +++ b/gcc/config/sh/predicates.md @@ -394,6 +394,18 @@ return 0; } + if ((mode == QImode || mode == HImode) + && (MEM_P (op) + || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op))))) + { + rtx x = XEXP ((MEM_P (op) ? op : SUBREG_REG (op)), 0); + + if (GET_CODE (x) == PLUS + && REG_P (XEXP (x, 0)) + && CONST_INT_P (XEXP (x, 1))) + return sh_legitimate_index_p (mode, XEXP (x, 1)); + } + if (TARGET_SHMEDIA && (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR) && sh_rep_vec (op, mode)) @@ -419,6 +431,18 @@ && ! (high_life_started || reload_completed)) return 0; + if ((mode == QImode || mode == HImode) + && (MEM_P (op) + || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op))))) + { + rtx x = XEXP ((MEM_P (op) ? op : SUBREG_REG (op)), 0); + + if (GET_CODE (x) == PLUS + && REG_P (XEXP (x, 0)) + && CONST_INT_P (XEXP (x, 1))) + return sh_legitimate_index_p (mode, XEXP (x, 1)); + } + return general_operand (op, mode); }) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 135087c8a45..7c9adb1ae6b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-06-02 Kaz Kojima + + PR target/49163 + * gcc.c-torture/compile/pr49163.c: New. + 2011-06-02 Asher Langton PR fortran/49268 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr49163.c b/gcc/testsuite/gcc.c-torture/compile/pr49163.c new file mode 100644 index 00000000000..f14ab1531e6 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr49163.c @@ -0,0 +1,35 @@ +/* PR target/49163 */ +struct S1 +{ + unsigned f0:18; + int f1; +} __attribute__ ((packed)); + +struct S2 +{ + volatile long long f0; + int f1; +}; + +struct S1 s1; +struct S2 s2; +const struct S2 s2array[2][1] = { }; + +struct S2 **sptr; + +extern int bar (char a, long long b, int * c, long long d, long long e); +extern int baz (void); + +int i; +int *ptr; + +void +foo (int *arg) +{ + for (i = 0; i < 1; i = baz()) + { + *arg = *(int *)sptr; + *ptr = bar (*arg, s2.f1, ptr, + bar (s2array[1][0].f0, *arg, ptr, s1.f1, *ptr), *arg); + } +} -- 2.30.2