re PR inline-asm/68843 (ICE with "u" input constraint)
authorBernd Edlinger <bernd.edlinger@hotmail.de>
Fri, 10 Jun 2016 12:22:21 +0000 (12:22 +0000)
committerBernd Edlinger <edlinger@gcc.gnu.org>
Fri, 10 Jun 2016 12:22:21 +0000 (12:22 +0000)
gcc:
2016-06-10  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        PR inline-asm/68843
        * reg-stack.c (check_asm_stack_operands): Explicit input arguments
        must be grouped on top of stack.  Don't force early clobber
        on ordinary reg outputs.

testsuite:
2016-06-10  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        PR inline-asm/68843
        * gcc.target/i386/pr68843-1.c: New test.
        * gcc.target/i386/pr68843-2.c: New test.

From-SVN: r237303

gcc/ChangeLog
gcc/reg-stack.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr68843-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr68843-2.c [new file with mode: 0644]

index 580dbed12c34d446c061a01d3a30a9b72c4069d4..d9852c5a25baf2c604e839f4875ce48cc410c03e 100644 (file)
@@ -1,3 +1,10 @@
+2016-06-10  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       PR inline-asm/68843
+       * reg-stack.c (check_asm_stack_operands): Explicit input arguments
+       must be grouped on top of stack.  Don't force early clobber
+       on ordinary reg outputs.
+
 2016-06-10  Richard Biener  <rguenther@suse.de>
 
        * targhooks.c (default_builtin_vectorization_cost): Adjust
index 89a7a11e0bcf5e9a6645fbdd2079d3f312387542..c931349f0f4287f6c3f3eb1a68a41dc8ffd5cbb3 100644 (file)
@@ -97,6 +97,9 @@
        All implicitly popped input regs must be closer to the top of
        the reg-stack than any input that is not implicitly popped.
 
+       All explicitly referenced input operands may not "skip" a reg.
+       Otherwise we can have holes in the stack.
+
    3. It is possible that if an input dies in an insn, reload might
       use the input reg for an output reload.  Consider this example:
 
@@ -461,6 +464,7 @@ check_asm_stack_operands (rtx_insn *insn)
 
   char reg_used_as_output[FIRST_PSEUDO_REGISTER];
   char implicitly_dies[FIRST_PSEUDO_REGISTER];
+  char explicitly_used[FIRST_PSEUDO_REGISTER];
 
   rtx *clobber_reg = 0;
   int n_inputs, n_outputs;
@@ -568,6 +572,7 @@ check_asm_stack_operands (rtx_insn *insn)
      popped.  */
 
   memset (implicitly_dies, 0, sizeof (implicitly_dies));
+  memset (explicitly_used, 0, sizeof (explicitly_used));
   for (i = n_outputs; i < n_outputs + n_inputs; i++)
     if (STACK_REG_P (recog_data.operand[i]))
       {
@@ -581,6 +586,8 @@ check_asm_stack_operands (rtx_insn *insn)
 
        if (j < n_clobbers || op_alt[i].matches >= 0)
          implicitly_dies[REGNO (recog_data.operand[i])] = 1;
+       else if (reg_class_size[(int) op_alt[i].cl] == 1)
+         explicitly_used[REGNO (recog_data.operand[i])] = 1;
       }
 
   /* Search for first non-popped reg.  */
@@ -600,6 +607,23 @@ check_asm_stack_operands (rtx_insn *insn)
       malformed_asm = 1;
     }
 
+  /* Search for first not-explicitly used reg.  */
+  for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
+    if (! implicitly_dies[i] && ! explicitly_used[i])
+      break;
+
+  /* If there are any other explicitly used regs, that's an error.  */
+  for (; i < LAST_STACK_REG + 1; i++)
+    if (explicitly_used[i])
+      break;
+
+  if (i != LAST_STACK_REG + 1)
+    {
+      error_for_asm (insn,
+                    "explicitly used regs must be grouped at top of stack");
+      malformed_asm = 1;
+    }
+
   /* Enforce rule #3: If any input operand uses the "f" constraint, all
      output constraints must use the "&" earlyclobber.
 
@@ -607,7 +631,7 @@ check_asm_stack_operands (rtx_insn *insn)
      record any earlyclobber.  */
 
   for (i = n_outputs; i < n_outputs + n_inputs; i++)
-    if (op_alt[i].matches == -1)
+    if (STACK_REG_P (recog_data.operand[i]) && op_alt[i].matches == -1)
       {
        int j;
 
index 325de75e2714389a70797817d3b8b139ac1576de..07c63895c6e5a2f4a8d927f816c03658b8410f1e 100644 (file)
@@ -1,3 +1,9 @@
+2016-06-10  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       PR inline-asm/68843
+       * gcc.target/i386/pr68843-1.c: New test.
+       * gcc.target/i386/pr68843-2.c: New test.
+
 2016-06-10  Thomas Schwinge  <thomas@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
 
diff --git a/gcc/testsuite/gcc.target/i386/pr68843-1.c b/gcc/testsuite/gcc.target/i386/pr68843-1.c
new file mode 100644 (file)
index 0000000..da0676a
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+double
+test ()
+{
+  double x = 1.0;
+  asm ("fld %1" /* { dg-error "explicitly used regs must be grouped at top of stack" } */
+       : "=&t" (x)
+       : "u" (x));
+  return x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr68843-2.c b/gcc/testsuite/gcc.target/i386/pr68843-2.c
new file mode 100644 (file)
index 0000000..652a5d3
--- /dev/null
@@ -0,0 +1,22 @@
+int
+__attribute__((noinline, noclone))
+test (double y)
+{
+  int a, b;
+  asm ("fistpl (%1)\n\t"
+       "movl (%1), %0"
+       : "=r" (a)
+       : "r" (&b), "t" (y)
+       : "st");
+  return a;
+}
+
+int
+main ()
+{
+  int t = -10;
+
+  if (test (t) != t)
+    __builtin_abort ();
+  return 0;
+}