diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-11-21 05:29:36 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-11-21 05:29:36 +0000 |
commit | 87fb8781228c96e8af2ef59cb3f930ca71af595b (patch) | |
tree | 0b5b40035eedaf847288f81a5c5be3bd4847c5e3 | |
parent | 66f8c851c9c4c25f995f4784e63ce2298f39329d (diff) | |
download | gcc-87fb8781228c96e8af2ef59cb3f930ca71af595b.tar.gz |
2016-11-20 Jeff Law <law@redhat.com>
PR target/48551
* reload.h (struct target_reload): Make x_double_reg_address_ok
be per-mode rather.
* reload.c (find_reloads_address): Check if double_reg_address_ok
is true for the mode of the memory reference.
* reload1.c (init_reload): Initialize double_reg_address_ok for
each mode.
PR target/48551
* gcc.target/m68k/pr48551.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@242648 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/reload.c | 2 | ||||
-rw-r--r-- | gcc/reload.h | 7 | ||||
-rw-r--r-- | gcc/reload1.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/m68k/pr48551.c | 44 |
6 files changed, 68 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 91cbe827157..40d6f8a5cbb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-11-20 Jeff Law <law@redhat.com> + + PR target/48551 + * reload.h (struct target_reload): Make x_double_reg_address_ok + be per-mode rather. + * reload.c (find_reloads_address): Check if double_reg_address_ok + is true for the mode of the memory reference. + * reload1.c (init_reload): Initialize double_reg_address_ok for + each mode. + 2016-11-20 Aldy Hernandez <aldyh@redhat.com> PR middle-end/61409 diff --git a/gcc/reload.c b/gcc/reload.c index 7d1681772b4..4cba2209451 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -5090,7 +5090,7 @@ find_reloads_address (machine_mode mode, rtx *memrefloc, rtx ad, loc = &XEXP (*loc, 0); } - if (double_reg_address_ok + if (double_reg_address_ok[mode] && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, as, PLUS, CONST_INT)) { diff --git a/gcc/reload.h b/gcc/reload.h index 98b75e3d819..1fc8ecb6cac 100644 --- a/gcc/reload.h +++ b/gcc/reload.h @@ -159,9 +159,6 @@ struct target_reload { which these are valid is the same as spill_indirect_levels, above. */ bool x_indirect_symref_ok; - /* Nonzero if an address (plus (reg frame_pointer) (reg ...)) is valid. */ - bool x_double_reg_address_ok; - /* Nonzero if indirect addressing is supported on the machine; this means that spilling (REG n) does not require reloading it into a register in order to do (MEM (REG n)) or (MEM (PLUS (REG n) (CONST_INT c))). The @@ -181,6 +178,10 @@ struct target_reload { [FIRST_PSEUDO_REGISTER] [MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1]); + /* Nonzero if an address (plus (reg frame_pointer) (reg ...)) is valid + in the given mode. */ + bool x_double_reg_address_ok[MAX_MACHINE_MODE]; + /* We will only make a register eligible for caller-save if it can be saved in its widest mode with a simple SET insn as long as the memory address is valid. We record the INSN_CODE is those insns here since diff --git a/gcc/reload1.c b/gcc/reload1.c index 4ee3840850e..b855268c025 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -448,11 +448,10 @@ init_reload (void) /* This way, we make sure that reg+reg is an offsettable address. */ tem = plus_constant (Pmode, tem, 4); - if (memory_address_p (QImode, tem)) - { - double_reg_address_ok = 1; - break; - } + for (int mode = 0; mode < MAX_MACHINE_MODE; mode++) + if (!double_reg_address_ok[mode] + && memory_address_p ((enum machine_mode)mode, tem)) + double_reg_address_ok[mode] = 1; } /* Initialize obstack for our rtl allocation. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6a23d906919..37e840321a5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-11-20 Jeff Law <law@redhat.com> + + PR target/48551 + * gcc.target/m68k/pr48551.c: New test. + 2016-11-20 Harald Anlauf <anlauf@gmx.de> PR fortran/69741 diff --git a/gcc/testsuite/gcc.target/m68k/pr48551.c b/gcc/testsuite/gcc.target/m68k/pr48551.c new file mode 100644 index 00000000000..48ea4b4940f --- /dev/null +++ b/gcc/testsuite/gcc.target/m68k/pr48551.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcpu=5475" } */ + +/* This tickles a problem with reload on the m68k. There's a reasonable + chance it will get stale over time. */ + +int frob; +typedef double SplashCoord; +void transform (SplashCoord xi, SplashCoord yi); +void +arf (SplashCoord x0, SplashCoord y0, SplashCoord x1, SplashCoord y1, + SplashCoord x2, SplashCoord y2, SplashCoord x3, SplashCoord y3, + SplashCoord * matrix, SplashCoord flatness2) +{ + SplashCoord cx[(1 << 10) + 1][3]; + SplashCoord cy[(1 << 10) + 1][3]; + SplashCoord xl0, xl1, xl2, xr0, xr1, xr2, xr3, xx1, xx2, xh; + SplashCoord yl0, yl1, yl2, yr0, yr1, yr2, yr3, yy1, yy2, yh; + int p1, p2, p3; + while (p1 < (1 << 10)) + { + xl0 = cx[p1][0]; + xx2 = cx[p1][2]; + yy2 = cy[p1][2]; + transform (xx2, yy2); + if (frob) + { + xl1 = (xl0 + xx1); + xh = (xx1 + xx2); + yl2 = (yl1 + yh); + xr2 = (xx2 + xr3); + yr2 = (yy2 + yr3) * 0.5; + xr1 = (xh + xr2); + yr1 = (yh + yr2); + xr0 = (xl2 + xr1); + yr0 = (yl2 + yr1); + cx[p1][1] = xl1; + cy[p1][1] = yl1; + cx[p1][2] = xl2; + cx[p3][0] = xr0; + cy[p3][0] = yr0; + } + } +} |