re PR inline-asm/56148 (inline asm matching constraint with different mode)
authorVladimir Makarov <vmakarov@redhat.com>
Tue, 12 Feb 2013 17:44:47 +0000 (17:44 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Tue, 12 Feb 2013 17:44:47 +0000 (17:44 +0000)
2013-02-12  Vladimir Makarov  <vmakarov@redhat.com>

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  <vmakarov@redhat.com>

PR inline-asm/56148
* gcc.target/i386/pr56148.c: New test.

From-SVN: r195988

gcc/ChangeLog
gcc/lra-constraints.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr56148.c [new file with mode: 0644]

index 4308b5b1f22d143dc19a62b506b5efbe6491de23..2e7171f2a04dc2b1c3021b13c7d5e2b34703f745 100644 (file)
@@ -1,3 +1,11 @@
+2013-02-12  Vladimir Makarov  <vmakarov@redhat.com>
+
+       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  <rguenther@suse.de>
 
        PR lto/56297
index 49c9723fc485199edb561049ef58d68207579a24..d3f4420b6a0013b9a267dfc28657fcfffbf1775f 100644 (file)
@@ -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++)
index ab009a5a46b475d7a5de3150bda7a14d7112cacd..7d07c20554a68f3adffa9dca1b2bbfbf7c3ee602 100644 (file)
@@ -1,3 +1,8 @@
+2013-02-12  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR inline-asm/56148
+       * gcc.target/i386/pr56148.c: New test.
+
 2013-02-12  Dominique d'Humieres  <dominiq@lps.ens.fr>
            Tobias Burnus  <burnus@net-b.de>
 
diff --git a/gcc/testsuite/gcc.target/i386/pr56148.c b/gcc/testsuite/gcc.target/i386/pr56148.c
new file mode 100644 (file)
index 0000000..78d2efb
--- /dev/null
@@ -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));
+}