aboutsummaryrefslogtreecommitdiff
path: root/gcc/sel-sched.c
diff options
context:
space:
mode:
authorAndrey Belevantsev <abel@ispras.ru>2016-03-12 20:12:29 +0300
committerJeff Law <law@gcc.gnu.org>2016-03-12 10:12:29 -0700
commitd0aca6abdbcbabc103df7a65e1e0dcbbad5e055e (patch)
tree31fa6bab43160c4b6f903cea42539f8bc86e59e2 /gcc/sel-sched.c
parentcefe08a4ec4ff2e8dadfc26f89e70be5a3f21a1f (diff)
downloadgcc-d0aca6abdbcbabc103df7a65e1e0dcbbad5e055e.zip
gcc-d0aca6abdbcbabc103df7a65e1e0dcbbad5e055e.tar.gz
gcc-d0aca6abdbcbabc103df7a65e1e0dcbbad5e055e.tar.bz2
re PR rtl-optimization/69307 (wrong code with -O2 -fselective-scheduling @ armv7a)
PR rtl-optimization/69307 * sel-sched.c (choose_best_pseudo_reg): Properly check for hard registers in modes that span more than one register. PR rtl-optimization/69307 * gcc.dg/pr69307.c: New test. From-SVN: r234163
Diffstat (limited to 'gcc/sel-sched.c')
-rw-r--r--gcc/sel-sched.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index bd32ab5..09cf028 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -1457,31 +1457,44 @@ choose_best_pseudo_reg (regset used_regs,
gcc_assert (mode == GET_MODE (dest));
orig_regno = REGNO (dest);
- if (!REGNO_REG_SET_P (used_regs, orig_regno))
- {
- if (orig_regno < FIRST_PSEUDO_REGISTER)
- {
- gcc_assert (df_regs_ever_live_p (orig_regno));
+ /* Check that nothing in used_regs intersects with orig_regno. When
+ we have a hard reg here, still loop over hard_regno_nregs. */
+ if (HARD_REGISTER_NUM_P (orig_regno))
+ {
+ int j, n;
+ for (j = 0, n = hard_regno_nregs[orig_regno][mode]; j < n; j++)
+ if (REGNO_REG_SET_P (used_regs, orig_regno + j))
+ break;
+ if (j < n)
+ continue;
+ }
+ else
+ {
+ if (REGNO_REG_SET_P (used_regs, orig_regno))
+ continue;
+ }
+ if (HARD_REGISTER_NUM_P (orig_regno))
+ {
+ gcc_assert (df_regs_ever_live_p (orig_regno));
- /* For hard registers, we have to check hardware imposed
- limitations (frame/stack registers, calls crossed). */
- if (!TEST_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs,
- orig_regno))
- {
- /* Don't let register cross a call if it doesn't already
- cross one. This condition is written in accordance with
- that in sched-deps.c sched_analyze_reg(). */
- if (!reg_rename_p->crosses_call
- || REG_N_CALLS_CROSSED (orig_regno) > 0)
- return gen_rtx_REG (mode, orig_regno);
- }
+ /* For hard registers, we have to check hardware imposed
+ limitations (frame/stack registers, calls crossed). */
+ if (!TEST_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs,
+ orig_regno))
+ {
+ /* Don't let register cross a call if it doesn't already
+ cross one. This condition is written in accordance with
+ that in sched-deps.c sched_analyze_reg(). */
+ if (!reg_rename_p->crosses_call
+ || REG_N_CALLS_CROSSED (orig_regno) > 0)
+ return gen_rtx_REG (mode, orig_regno);
+ }
- bad_hard_regs = true;
- }
- else
- return dest;
- }
- }
+ bad_hard_regs = true;
+ }
+ else
+ return dest;
+ }
*is_orig_reg_p_ptr = false;