diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/lra-constraints.cc | 40 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.target/xstormy16/pr118358.c | 90 |
2 files changed, 130 insertions, 0 deletions
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 82cf0a829bf..d843226c8c8 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -4960,7 +4960,47 @@ curr_insn_transform (bool check_only_p) } lra_assert (done_p); } + int const_regno = -1; + rtx set; + rtx_insn *prev, *const_insn = NULL; + if (before != NULL_RTX && (prev = PREV_INSN (curr_insn)) != NULL_RTX + && (set = single_set (prev)) != NULL_RTX && CONSTANT_P (SET_SRC (set))) + { + rtx reg = SET_DEST (set); + if (GET_CODE (reg) == SUBREG) + reg = SUBREG_REG (reg); + /* Consider only reload insns as we don't want to change the order + created by previous optimizations. */ + if (REG_P (reg) && (int) REGNO (reg) >= lra_new_regno_start + && bitmap_bit_p (&lra_reg_info[REGNO (reg)].insn_bitmap, + INSN_UID (curr_insn))) + { + const_regno = REGNO (reg); + const_insn = prev; + } + } lra_process_new_insns (curr_insn, before, after, "Inserting insn reload"); + if (const_regno >= 0) { + bool move_p = true; + for (rtx_insn *insn = before; insn != curr_insn; insn = NEXT_INSN (insn)) + if (bitmap_bit_p (&lra_reg_info[const_regno].insn_bitmap, + INSN_UID (insn))) + { + move_p = false; + break; + } + if (move_p) + { + reorder_insns_nobb (const_insn, const_insn, PREV_INSN (curr_insn)); + if (lra_dump_file != NULL) + { + dump_insn_slim (lra_dump_file, const_insn); + fprintf (lra_dump_file, + " to decrease reg pressure, it is moved before:\n"); + dump_insn_slim (lra_dump_file, curr_insn); + } + } + } return change_p; } diff --git a/gcc/testsuite/gcc.target/xstormy16/pr118358.c b/gcc/testsuite/gcc.target/xstormy16/pr118358.c new file mode 100644 index 00000000000..0743a023586 --- /dev/null +++ b/gcc/testsuite/gcc.target/xstormy16/pr118358.c @@ -0,0 +1,90 @@ +/* PR target/118358. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern void exit (int); + +typedef struct +{ + union + { + struct + { + unsigned char a3; + unsigned char a4; + } a2; + unsigned int a5; + } a0; + unsigned int a1; +} A; + +static int +foo (unsigned int *b, unsigned int n, unsigned int s, const unsigned int *d, + const unsigned int *e, A **t, unsigned int *m, A *hp, unsigned int *hn, + unsigned int *v) +{ + unsigned int a, c[15 + 1], f; + int g, h; + unsigned int i, j, k; + int l; + unsigned int ee; + unsigned int *p; + A *q, r, *u[15]; + int w; + unsigned int x[15 + 1], *xx; + int y; + unsigned int z; + for (j = 1; j <= 15; j++) + if (c[j]) + break; + if ((unsigned int) l < j) + l = j; + for (i = 15; i; i--) + if (c[i]) + break; + g = i; + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return -3; + h = -1; + z = 0; + for (; k <= g; k++) + { + while (k > w + l) + { + h++; + w += l; + if ((f = 1 << (j = k - w)) > a + 1) + ; + z = 1 << j; + if (*hn + z > 1440) + return -3; + u[h] = q = hp + *hn; + r.a0.a2.a4 = (unsigned char) l; + r.a1 = (unsigned int) (q - u[h - 1] - j); + } + for (j = i >> w; j < z; j += f) + q[j] = r; + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + while ((i & ee) != x[h]) + { + h--; + w -= l; + } + } + return y != 0 && g != 1 ? (-5) : 0; +} + +unsigned int a[19] = { 3, 4, 0, 2, 2, [17] = 3, 3 }; +unsigned int d[19]; +A h[1440]; + +int +main (void) +{ + unsigned int b = 0, c = 0; + A *e = 0; + foo (a, 19, 19, 0, 0, &e, &b, h, &c, d); + exit (0); +} |
