re PR inline-asm/55934 (LRA inline asm error recovery)
authorSteven Bosscher <steven@gcc.gnu.org>
Thu, 24 Jan 2013 10:30:26 +0000 (10:30 +0000)
committerSteven Bosscher <steven@gcc.gnu.org>
Thu, 24 Jan 2013 10:30:26 +0000 (10:30 +0000)
gcc/

PR inline-asm/55934
* lra-assigns.c (assign_by_spills): Throw away the pattern of asms
that have operands with impossible constraints.
Add a FIXME for a speed-up opportunity.
* lra-constraints.c (process_alt_operands): Verify that a class
selected from constraints on asms is valid for the operand mode.
(curr_insn_transform): Remove incorrect comment.

testsuite/

PR inline-asm/55934
* gcc.target/i386/pr55934.c: New test.

From-SVN: r195420

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

index 3bf5cf5a372b0a767b7816202a34c56ca05df3e9..eedd4d6d8dc97aa5e21de3830eff0ccfa877c093 100644 (file)
@@ -1,3 +1,13 @@
+2013-01-24  Steven Bosscher  <steven@gcc.gnu.org>
+
+       PR inline-asm/55934
+       * lra-assigns.c (assign_by_spills): Throw away the pattern of asms
+       that have operands with impossible constraints.
+       Add a FIXME for a speed-up opportunity.
+       * lra-constraints.c (process_alt_operands): Verify that a class
+       selected from constraints on asms is valid for the operand mode.
+       (curr_insn_transform): Remove incorrect comment.
+
 2013-01-23  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.md (*movdf_internal_rex64): Disparage alternatives
index 578bcaeda89fe936ba5f91400b40356d94da4bab..33666fd07b11c698193c294c1d6dee27b72f5986 100644 (file)
@@ -1240,6 +1240,23 @@ assign_by_spills (void)
                  asm_p = true;
                  error_for_asm (insn,
                                 "%<asm%> operand has impossible constraints");
+                 /* Avoid further trouble with this insn.
+                    For asm goto, instead of fixing up all the edges
+                    just clear the template and clear input operands
+                    (asm goto doesn't have any output operands).  */
+                 if (JUMP_P (insn))
+                   {
+                     rtx asm_op = extract_asm_operands (PATTERN (insn));
+                     ASM_OPERANDS_TEMPLATE (asm_op) = ggc_strdup ("");
+                     ASM_OPERANDS_INPUT_VEC (asm_op) = rtvec_alloc (0);
+                     ASM_OPERANDS_INPUT_CONSTRAINT_VEC (asm_op) = rtvec_alloc (0);
+                     lra_update_insn_regno_info (insn);
+                   }
+                 else
+                   {
+                     PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
+                     lra_set_insn_deleted (insn);
+                   }
                }
            }
          lra_assert (asm_p);
@@ -1263,6 +1280,9 @@ assign_by_spills (void)
          bitmap_ior_into (&changed_insns,
                           &lra_reg_info[sorted_pseudos[i]].insn_bitmap);
        }
+
+      /* FIXME: Look up the changed insns in the cached LRA insn data using
+        an EXECUTE_IF_SET_IN_BITMAP over changed_insns.  */
       FOR_EACH_BB (bb)
        FOR_BB_INSNS (bb, insn)
        if (bitmap_bit_p (&changed_insns, INSN_UID (insn)))
index 01c8cf143cfdc2bcb3a28c130922555f8dbca626..03728b78f42a66e752f7887ffd70a5b594f5922f 100644 (file)
@@ -1847,11 +1847,27 @@ process_alt_operands (int only_alternative)
              int const_to_mem = 0;
              bool no_regs_p;
 
+             /* If this alternative asks for a specific reg class, see if there
+                is at least one allocatable register in that class.  */
              no_regs_p
                = (this_alternative == NO_REGS
                   || (hard_reg_set_subset_p
                       (reg_class_contents[this_alternative],
                        lra_no_alloc_regs)));
+
+             /* For asms, verify that the class for this alternative is possible
+                for the mode that is specified.  */
+             if (!no_regs_p && REG_P (op) && INSN_CODE (curr_insn) < 0)
+               {
+                 int i;
+                 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+                   if (HARD_REGNO_MODE_OK (i, mode)
+                       && in_hard_reg_set_p (reg_class_contents[this_alternative], mode, i))
+                     break;
+                 if (i == FIRST_PSEUDO_REGISTER)
+                   winreg = false;
+               }
+
              /* If this operand accepts a register, and if the
                 register class has at least one allocatable register,
                 then this operand can be reloaded.  */
@@ -2742,10 +2758,6 @@ curr_insn_transform (void)
        swap_operands (commutative);
     }
 
-  /* The operands don't meet the constraints.  goal_alt describes the
-     alternative that we could reach by reloading the fewest operands.
-     Reload so as to fit it.  */
-
   if (! alt_p && ! sec_mem_p)
     {
       /* No alternative works with reloads??  */
index 8bcbca513a24f1395c7b22d43d9632edbef6f5c2..9dda502e093228cfd5bc61031ac025b7112e9e4b 100644 (file)
@@ -1,3 +1,8 @@
+2013-01-24  Steven Bosscher  <steven@gcc.gnu.org>
+
+       PR inline-asm/55934
+       * gcc.target/i386/pr55934.c: New test.
+
 2013-01-23  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/56081
diff --git a/gcc/testsuite/gcc.target/i386/pr55934.c b/gcc/testsuite/gcc.target/i386/pr55934.c
new file mode 100644 (file)
index 0000000..ea48955
--- /dev/null
@@ -0,0 +1,11 @@
+/* PR inline-asm/55934 */
+/* { dg-do compile } */
+/* { dg-require-effective-target sse } */
+/* { dg-options "-std=c99 -msse" } */
+_Complex float
+foo (void)
+{
+  _Complex float x;
+  __asm ("" : "=x" (x)); /* { dg-error "inconsistent .* constraint" } */
+  return x;
+}