From 1c86bd80a3fc159b7b8b56b531790d87ff2556c9 Mon Sep 17 00:00:00 2001 From: Vladimir Makarov Date: Tue, 12 Feb 2013 17:44:47 +0000 Subject: [PATCH] re PR inline-asm/56148 (inline asm matching constraint with different mode) 2013-02-12 Vladimir Makarov PR inline-asm/56148 * lra-constraints.c (process_alt_operands): Match early clobber operand with itself. Check conflicts with earlyclobner only if the operand is not reloaded. Prefer to reload conflicting operand if earlyclobber and matching operands are the same. 2013-02-12 Vladimir Makarov PR inline-asm/56148 * gcc.target/i386/pr56148.c: New test. From-SVN: r195988 --- gcc/ChangeLog | 8 ++++ gcc/lra-constraints.c | 60 ++++++++++++++++--------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.target/i386/pr56148.c | 12 +++++ 4 files changed, 65 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr56148.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4308b5b1f22..2e7171f2a04 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2013-02-12 Vladimir Makarov + + PR inline-asm/56148 + * lra-constraints.c (process_alt_operands): Match early clobber + operand with itself. Check conflicts with earlyclobner only if + the operand is not reloaded. Prefer to reload conflicting operand + if earlyclobber and matching operands are the same. + 2013-02-12 Richard Biener PR lto/56297 diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 49c9723fc48..d3f4420b6a0 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1533,8 +1533,8 @@ process_alt_operands (int only_alternative) if (! curr_static_id->operand[m].early_clobber || operand_reg[nop] == NULL_RTX || (find_regno_note (curr_insn, REG_DEAD, - REGNO (operand_reg[nop])) - != NULL_RTX)) + REGNO (op)) + || REGNO (op) == REGNO (operand_reg[m]))) match_p = true; } if (match_p) @@ -2059,6 +2059,7 @@ process_alt_operands (int only_alternative) if ((! curr_alt_win[i] && ! curr_alt_match_win[i]) || hard_regno[i] < 0) continue; + lra_assert (operand_reg[i] != NULL_RTX); clobbered_hard_regno = hard_regno[i]; CLEAR_HARD_REG_SET (temp_set); add_to_hard_reg_set (&temp_set, biggest_mode[i], clobbered_hard_regno); @@ -2073,30 +2074,49 @@ process_alt_operands (int only_alternative) else if ((curr_alt_matches[j] == i && curr_alt_match_win[j]) || (curr_alt_matches[i] == j && curr_alt_match_win[i])) continue; - else if (uses_hard_regs_p (*curr_id->operand_loc[j], temp_set)) + /* If we don't reload j-th operand, check conflicts. */ + else if ((curr_alt_win[j] || curr_alt_match_win[j]) + && uses_hard_regs_p (*curr_id->operand_loc[j], temp_set)) break; if (j >= n_operands) continue; - /* We need to reload early clobbered register. */ - for (j = 0; j < n_operands; j++) - if (curr_alt_matches[j] == i) - { - curr_alt_match_win[j] = false; - losers++; - overall += LRA_LOSER_COST_FACTOR; - } - if (! curr_alt_match_win[i]) - curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = i; + /* 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 (operand_reg[j] != NULL_RTX && ! curr_alt_match_win[j] + && REGNO (operand_reg[i]) == REGNO (operand_reg[j])) + { + curr_alt_win[j] = false; + curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = j; + losers++; + overall += LRA_LOSER_COST_FACTOR; + } else { - /* Remember pseudos used for match reloads are never - inherited. */ - lra_assert (curr_alt_matches[i] >= 0); - curr_alt_win[curr_alt_matches[i]] = false; + /* We need to reload early clobbered register and the + matched registers. */ + for (j = 0; j < n_operands; j++) + if (curr_alt_matches[j] == i) + { + curr_alt_match_win[j] = false; + losers++; + overall += LRA_LOSER_COST_FACTOR; + } + if (! curr_alt_match_win[i]) + curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = i; + else + { + /* Remember pseudos used for match reloads are never + inherited. */ + lra_assert (curr_alt_matches[i] >= 0); + curr_alt_win[curr_alt_matches[i]] = false; + } + curr_alt_win[i] = curr_alt_match_win[i] = false; + losers++; + overall += LRA_LOSER_COST_FACTOR; } - curr_alt_win[i] = curr_alt_match_win[i] = false; - losers++; - overall += LRA_LOSER_COST_FACTOR; } small_class_operands_num = 0; for (nop = 0; nop < n_operands; nop++) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ab009a5a46b..7d07c20554a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-02-12 Vladimir Makarov + + PR inline-asm/56148 + * gcc.target/i386/pr56148.c: New test. + 2013-02-12 Dominique d'Humieres Tobias Burnus diff --git a/gcc/testsuite/gcc.target/i386/pr56148.c b/gcc/testsuite/gcc.target/i386/pr56148.c new file mode 100644 index 00000000000..78d2efba191 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr56148.c @@ -0,0 +1,12 @@ +/* PR inline-asm/56148 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void +foo (void) +{ + unsigned char e[16]; + unsigned long a, b, c, d; + __asm__ __volatile__ ("" : "=d" (a), "=&c" (c), "=&D" (d), "=&a" (b) + : "0" (-1U), "mr" (e), "1" (128 >> 5), "2" (e), "3" (-1U)); +} -- 2.30.2