]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/30262 (ICE with nested fn accessed var in asm "m" constraint)
authorJakub Jelinek <jakub@redhat.com>
Thu, 21 Dec 2006 13:13:15 +0000 (14:13 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 21 Dec 2006 13:13:15 +0000 (14:13 +0100)
PR middle-end/30262
PR middle-end/30263
* tree-nested.c (walk_asm_expr): New function.
(walk_stmts): Use it for ASM_EXPR.

* gcc.c-torture/execute/20061220-1.c: New test.
* gcc.dg/gomp/asm-1.c: New test.

From-SVN: r120106

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20061220-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/asm-1.c [new file with mode: 0644]
gcc/tree-nested.c

index f3e2559d2a6cfd8f39eee0d57f65615ad862d32a..8d85e15725619f2e4afedea073b061213b9c463c 100644 (file)
@@ -1,5 +1,10 @@
 2006-12-21  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/30262
+       PR middle-end/30263
+       * tree-nested.c (walk_asm_expr): New function.
+       (walk_stmts): Use it for ASM_EXPR.
+
        PR target/30230
        * config/ia64/ia64.c (ia64_add_bundle_selector_before): New function.
        (bundling): Use it.
index 84b2cd8f043900754f67e10ba24ca9bd56e20f78..c5739dea6cbb52fe65dc84e9be7666202fd01459 100644 (file)
@@ -1,5 +1,11 @@
 2006-12-21  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/30262
+       * gcc.c-torture/execute/20061220-1.c: New test.
+
+       PR middle-end/30263
+       * gcc.dg/gomp/asm-1.c: New test.
+
        PR target/30230
        * g++.dg/eh/ia64-2.C: New test.
 
diff --git a/gcc/testsuite/gcc.c-torture/execute/20061220-1.c b/gcc/testsuite/gcc.c-torture/execute/20061220-1.c
new file mode 100644 (file)
index 0000000..188f92c
--- /dev/null
@@ -0,0 +1,72 @@
+/* PR middle-end/30262 */
+extern void abort (void);
+
+int
+foo (void)
+{
+  unsigned int x = 0;
+
+  void nested (void)
+  {
+    x = 254;
+  }
+
+  nested ();
+  asm volatile ("" :: "r" (x));
+  asm volatile ("" :: "m" (x));
+  asm volatile ("" :: "mr" (x));
+  asm volatile ("" : "=r" (x) : "0" (x));
+  asm volatile ("" : "=m" (x) : "m" (x));
+  return x;
+}
+
+int
+bar (void)
+{
+  unsigned int x = 0;
+
+  void nested (void)
+  {
+    asm volatile ("" :: "r" (x));
+    asm volatile ("" :: "m" (x));
+    asm volatile ("" :: "mr" (x));
+    x += 4;
+    asm volatile ("" : "=r" (x) : "0" (x));
+    asm volatile ("" : "=m" (x) : "m" (x));
+  }
+
+  nested ();
+  return x;
+}
+
+int
+baz (void)
+{
+  unsigned int x = 0;
+
+  void nested (void)
+  {
+    void nested2 (void)
+    {
+      asm volatile ("" :: "r" (x));
+      asm volatile ("" :: "m" (x));
+      asm volatile ("" :: "mr" (x));
+      x += 4;
+      asm volatile ("" : "=r" (x) : "0" (x));
+      asm volatile ("" : "=m" (x) : "m" (x));
+    }
+    nested2 ();
+    nested2 ();
+  }
+
+  nested ();
+  return x;
+}
+
+int
+main (void)
+{
+  if (foo () != 254 || bar () != 4 || baz () != 8)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/asm-1.c b/gcc/testsuite/gcc.dg/gomp/asm-1.c
new file mode 100644 (file)
index 0000000..ced31f3
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR middle-end/30263 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp" } */
+
+void
+foo (void)
+{
+  int s0, s1 = 5, s2 = 6;
+  int p0, p1, p2;
+  int f0 = 4, f1 = 5, f2 = 6;
+#pragma omp parallel shared (s0, s1, s2) private (p0, p1, p2) \
+           firstprivate (f0, f1, f2)
+  {
+    asm ("" : "=m" (p0) : "m" (p1), "mr" (p2));
+    if (omp_get_thread_num () == 0)
+      asm ("" : "=m" (s0) : "m" (s1), "mr" (s2));
+    asm ("" : "=m" (f0) : "m" (f1), "mr" (f2));
+  }
+}
index 42aef32884193b47f76fd803f6e192a189b67afc..166debb22c003ee7a0e109b1de5c8075207817d0 100644 (file)
@@ -546,6 +546,47 @@ get_nl_goto_field (struct nesting_info *info)
   return field;
 }
 \f
+/* Helper function for walk_stmts.  Walk output operands of an ASM_EXPR.  */
+
+static void
+walk_asm_expr (struct walk_stmt_info *wi, tree stmt)
+{
+  int noutputs = list_length (ASM_OUTPUTS (stmt));
+  const char **oconstraints
+    = (const char **) alloca ((noutputs) * sizeof (const char *));
+  int i;
+  tree link;
+  const char *constraint;
+  bool allows_mem, allows_reg, is_inout;
+
+  wi->is_lhs = true;
+  for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
+    {
+      constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+      oconstraints[i] = constraint;
+      parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
+                              &allows_reg, &is_inout);
+
+      wi->val_only = (allows_reg || !allows_mem);
+      walk_tree (&TREE_VALUE (link), wi->callback, wi, NULL);
+    }
+
+  for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
+    {
+      constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+      parse_input_constraint (&constraint, 0, 0, noutputs, 0,
+                             oconstraints, &allows_mem, &allows_reg);
+
+      wi->val_only = (allows_reg || !allows_mem);
+      /* Although input "m" is not really a LHS, we need a lvalue.  */
+      wi->is_lhs = !wi->val_only;
+      walk_tree (&TREE_VALUE (link), wi->callback, wi, NULL);
+    }
+
+  wi->is_lhs = false;
+  wi->val_only = true;
+}
+
 /* Iterate over all sub-statements of *TP calling walk_tree with
    WI->CALLBACK for every sub-expression in each statement found.  */
 
@@ -628,6 +669,10 @@ walk_stmts (struct walk_stmt_info *wi, tree *tp)
       wi->is_lhs = false;
       break;
 
+    case ASM_EXPR:
+      walk_asm_expr (wi, *tp);
+      break;
+
     default:
       wi->val_only = true;
       walk_tree (tp, wi->callback, wi, NULL);