re PR middle-end/30262 (ICE with nested fn accessed var in asm "m" constraint)
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
This commit is contained in:
parent
4a4cd49c06
commit
5075abae44
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue