aboutsummaryrefslogtreecommitdiff
path: root/gcc/sel-sched.c
diff options
context:
space:
mode:
authorAndrey Belevantsev <abel@ispras.ru>2016-03-12 17:12:29 +0000
committerJeff Law <law@redhat.com>2016-03-12 17:12:29 +0000
commit05509a864fca028fc628de92e9d68ad9676b78b5 (patch)
tree31fa6bab43160c4b6f903cea42539f8bc86e59e2 /gcc/sel-sched.c
parent894f2153b79d7549f4f617a3b77618d624f3d85a (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@234163 138bc75d-0d04-0410-961f-82ee72b054a4
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 bd32ab5c154..09cf0284603 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;