aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20061220-1.c72
-rw-r--r--gcc/testsuite/gcc.dg/gomp/asm-1.c19
-rw-r--r--gcc/tree-nested.c45
5 files changed, 147 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f3e2559..8d85e15 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 84b2cd8..c5739de 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..188f92c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20061220-1.c
@@ -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
index 0000000..ced31f3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/asm-1.c
@@ -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));
+ }
+}
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 42aef32..166debb 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -546,6 +546,47 @@ get_nl_goto_field (struct nesting_info *info)
return field;
}
+/* 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);