diff options
author | Peter Bergner <bergner@linux.ibm.com> | 2018-11-08 22:39:45 +0000 |
---|---|---|
committer | Peter Bergner <bergner@gcc.gnu.org> | 2018-11-08 16:39:45 -0600 |
commit | 2f0b80c7a4ab4254f57ba63de26ebb7896e3742d (patch) | |
tree | 0b641c23205b2def0563667593bc61bb7bc6e042 /gcc/lra-constraints.c | |
parent | 39abbb865c2363ab508bdf5dc24553e448c803b0 (diff) | |
download | gcc-2f0b80c7a4ab4254f57ba63de26ebb7896e3742d.zip gcc-2f0b80c7a4ab4254f57ba63de26ebb7896e3742d.tar.gz gcc-2f0b80c7a4ab4254f57ba63de26ebb7896e3742d.tar.bz2 |
re PR rtl-optimization/87600 (Fix for PRs 86939 and 87479 causes build issues for several targets)
gcc/
PR rtl-optimization/87600
* cfgexpand.c (expand_asm_stmt): Catch illegal asm constraint usage.
* lra-constraints.c (process_alt_operands): Skip illegal hard
register usage. Prefer reloading non hard register operands.
gcc/testsuite/
PR rtl-optimization/87600
* gcc.dg/pr87600.h: New file.
* gcc.dg/pr87600-1.c: New test.
* gcc.dg/pr87600-2.c: Likewise.
From-SVN: r265942
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r-- | gcc/lra-constraints.c | 60 |
1 files changed, 48 insertions, 12 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index ab61989..88546d2 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -2146,9 +2146,32 @@ process_alt_operands (int only_alternative) } else { - /* Operands don't match. Both operands must - allow a reload register, otherwise we - cannot make them match. */ + /* Operands don't match. If the operands are + different user defined explicit hard registers, + then we cannot make them match. */ + if ((REG_P (*curr_id->operand_loc[nop]) + || SUBREG_P (*curr_id->operand_loc[nop])) + && (REG_P (*curr_id->operand_loc[m]) + || SUBREG_P (*curr_id->operand_loc[m]))) + { + rtx nop_reg = *curr_id->operand_loc[nop]; + if (SUBREG_P (nop_reg)) + nop_reg = SUBREG_REG (nop_reg); + rtx m_reg = *curr_id->operand_loc[m]; + if (SUBREG_P (m_reg)) + m_reg = SUBREG_REG (m_reg); + + if (REG_P (nop_reg) + && HARD_REGISTER_P (nop_reg) + && REG_USERVAR_P (nop_reg) + && REG_P (m_reg) + && HARD_REGISTER_P (m_reg) + && REG_USERVAR_P (m_reg)) + break; + } + + /* Both operands must allow a reload register, + otherwise we cannot make them match. */ if (curr_alt[m] == NO_REGS) break; /* Retroactively mark the operand we had to @@ -2910,18 +2933,31 @@ process_alt_operands (int only_alternative) if (first_conflict_j < 0) first_conflict_j = j; last_conflict_j = j; + /* Both the earlyclobber operand and conflicting operand + cannot both be user defined hard registers. */ + if (HARD_REGISTER_P (operand_reg[i]) + && REG_USERVAR_P (operand_reg[i]) + && operand_reg[j] != NULL_RTX + && HARD_REGISTER_P (operand_reg[j]) + && REG_USERVAR_P (operand_reg[j])) + fatal_insn ("unable to generate reloads for " + "impossible constraints:", curr_insn); } if (last_conflict_j < 0) continue; - /* If earlyclobber operand conflicts with another - non-matching operand which is actually the same register - as the earlyclobber operand, it is better to reload the - another operand as an operand matching the earlyclobber - operand can be also the same. */ - if (first_conflict_j == last_conflict_j - && operand_reg[last_conflict_j] != NULL_RTX - && ! curr_alt_match_win[last_conflict_j] - && REGNO (operand_reg[i]) == REGNO (operand_reg[last_conflict_j])) + + /* If an earlyclobber operand conflicts with another non-matching + operand (ie, they have been assigned the same hard register), + then it is better to reload the other operand, as there may + exist yet another operand with a matching constraint associated + with the earlyclobber operand. However, if one of the operands + is an explicit use of a hard register, then we must reload the + other non-hard register operand. */ + if (HARD_REGISTER_P (operand_reg[i]) + || (first_conflict_j == last_conflict_j + && operand_reg[last_conflict_j] != NULL_RTX + && !curr_alt_match_win[last_conflict_j] + && !HARD_REGISTER_P (operand_reg[last_conflict_j]))) { curr_alt_win[last_conflict_j] = false; curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] |