From 4692943dace8ba6e1fc3edc6e1c2b051a81b74b7 Mon Sep 17 00:00:00 2001 From: Bernd Schmidt Date: Tue, 14 Mar 2017 11:50:46 -0600 Subject: [PATCH] re PR rtl-optimization/79728 (ICE in setup_pressure_classes, at ira.c:912) PR rtl-optimization/79728 * regs.h (struct target_regs): New field x_contains_allocatable_regs_of_mode. (contains_allocatable_regs_of_mode): New macro. * reginfo.c (init_reg_sets_1): Initialize it, and change contains_reg_of_mode so it includes global regs as well. * reload.c (push_reload): Use contains_allocatable_regs_of_mode rather than contains_regs_of_mode. PR rtl-optimization/79728 * gcc.target/i386/sse-globalreg.c: New test. From-SVN: r246138 --- gcc/ChangeLog | 11 ++++++++++ gcc/reginfo.c | 20 ++++++++++++++----- gcc/regs.h | 6 ++++++ gcc/reload.c | 4 ++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/i386/sse-globalreg.c | 6 ++++++ 6 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/sse-globalreg.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 29987fe4ae9..c6f0dd524da 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2017-03-14 Bernd Schmidt + + PR rtl-optimization/79728 + * regs.h (struct target_regs): New field + x_contains_allocatable_regs_of_mode. + (contains_allocatable_regs_of_mode): New macro. + * reginfo.c (init_reg_sets_1): Initialize it, and change + contains_reg_of_mode so it includes global regs as well. + * reload.c (push_reload): Use contains_allocatable_regs_of_mode + rather than contains_regs_of_mode. + 2017-03-14 Martin Liska * doc/invoke.texi: Document options that can't be combined with diff --git a/gcc/reginfo.c b/gcc/reginfo.c index a2e0b681281..a7df02d3274 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -468,19 +468,29 @@ init_reg_sets_1 (void) memset (contains_reg_of_mode, 0, sizeof (contains_reg_of_mode)); for (m = 0; m < (unsigned int) MAX_MACHINE_MODE; m++) { - HARD_REG_SET ok_regs; + HARD_REG_SET ok_regs, ok_regs2; CLEAR_HARD_REG_SET (ok_regs); + CLEAR_HARD_REG_SET (ok_regs2); for (j = 0; j < FIRST_PSEUDO_REGISTER; j++) - if (!fixed_regs [j] && HARD_REGNO_MODE_OK (j, (machine_mode) m)) - SET_HARD_REG_BIT (ok_regs, j); + if (!TEST_HARD_REG_BIT (fixed_nonglobal_reg_set, j) + && HARD_REGNO_MODE_OK (j, (machine_mode) m)) + { + SET_HARD_REG_BIT (ok_regs, j); + if (!fixed_regs[j]) + SET_HARD_REG_BIT (ok_regs2, j); + } for (i = 0; i < N_REG_CLASSES; i++) if ((targetm.class_max_nregs ((reg_class_t) i, (machine_mode) m) <= reg_class_size[i]) && hard_reg_set_intersect_p (ok_regs, reg_class_contents[i])) { - contains_reg_of_mode [i][m] = 1; - have_regs_of_mode [m] = 1; + contains_reg_of_mode[i][m] = 1; + if (hard_reg_set_intersect_p (ok_regs2, reg_class_contents[i])) + { + have_regs_of_mode[m] = 1; + contains_allocatable_reg_of_mode[i][m] = 1; + } } } } diff --git a/gcc/regs.h b/gcc/regs.h index 09c8da439ee..bdaa9ba0639 100644 --- a/gcc/regs.h +++ b/gcc/regs.h @@ -218,6 +218,10 @@ struct target_regs { /* 1 if the corresponding class contains a register of the given mode. */ char x_contains_reg_of_mode[N_REG_CLASSES][MAX_MACHINE_MODE]; + /* 1 if the corresponding class contains a register of the given mode + which is not global and can therefore be allocated. */ + char x_contains_allocatable_reg_of_mode[N_REG_CLASSES][MAX_MACHINE_MODE]; + /* Record for each mode whether we can move a register directly to or from an object of that mode in memory. If we can't, we won't try to use that mode directly when accessing a field of that mode. */ @@ -243,6 +247,8 @@ extern struct target_regs *this_target_regs; (this_target_regs->x_have_regs_of_mode) #define contains_reg_of_mode \ (this_target_regs->x_contains_reg_of_mode) +#define contains_allocatable_reg_of_mode \ + (this_target_regs->x_contains_allocatable_reg_of_mode) #define direct_load \ (this_target_regs->x_direct_load) #define direct_store \ diff --git a/gcc/reload.c b/gcc/reload.c index 9d27a7cdda2..598b78d6ef4 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -1055,7 +1055,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, #ifdef CANNOT_CHANGE_MODE_CLASS && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, rclass) #endif - && contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (in))] + && contains_allocatable_reg_of_mode[rclass][GET_MODE (SUBREG_REG (in))] && (CONSTANT_P (SUBREG_REG (in)) || GET_CODE (SUBREG_REG (in)) == PLUS || strict_low @@ -1164,7 +1164,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, #ifdef CANNOT_CHANGE_MODE_CLASS && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, rclass) #endif - && contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (out))] + && contains_allocatable_reg_of_mode[rclass][GET_MODE (SUBREG_REG (out))] && (CONSTANT_P (SUBREG_REG (out)) || strict_low || (((REG_P (SUBREG_REG (out)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index eec5c79acf7..8e7a1dda435 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-03-14 Bernd Schmidt + + PR rtl-optimization/79728 + * gcc.target/i386/sse-globalreg.c: New test. + 2017-03-14 Martin Liska PR lto/66295 diff --git a/gcc/testsuite/gcc.target/i386/sse-globalreg.c b/gcc/testsuite/gcc.target/i386/sse-globalreg.c new file mode 100644 index 00000000000..818a2b63b8d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse-globalreg.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse2 -w" } */ +/* { dg-require-effective-target sse2 } */ + +register int a __asm__("xmm0"); +void fn1() {} -- 2.30.2