On Tue, 19 Jan 2016, Jakub Jelinek wrote: > Hi! > > Here is an attempt to fix ICE on statement expression in "m" asm input > operand. The problem is that gimplify_asm_expr attempts to mark it > addressable, but that can be just too late, a temporary the stmt-expression > gimplifies to might not be addressable and may be used already in the > gimplified code. Normally the C/C++ FEs attempt to mark the operand > addressable already, but in case of statement expression the temporaries > might not exist yet. > The patch turns also the PR29119 testcase into invalid test, but you've > already said in that PR it should be invalid and I agree with that.
Hmm, but can't we detect this in the FE? > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? What happens if we just do _not_ mark the memory input addressable? Shouldn't IRA/LRA in the end satisfy the constraint by spilling a non-memory input and using the spill slot? Richard. > 2016-01-19 Jakub Jelinek <ja...@redhat.com> > > PR middle-end/67653 > * gimplify.c (gimplify_asm_expr): Error if it is too late to > attempt to mark memory input operand addressable. > > * c-c++-common/pr67653.c: New test. > * gcc.dg/torture/pr29119.c: Add dg-error. > > --- gcc/gimplify.c.jj 2016-01-15 20:37:30.000000000 +0100 > +++ gcc/gimplify.c 2016-01-18 16:05:21.125640974 +0100 > @@ -5305,6 +5305,27 @@ gimplify_asm_expr (tree *expr_p, gimple_ > TREE_VALUE (link) = error_mark_node; > tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, > is_gimple_lvalue, fb_lvalue | fb_mayfail); > + if (tret != GS_ERROR) > + { > + /* Unlike output operands, memory inputs are not guaranteed > + to be lvalues by the FE, and while the expressions are > + marked addressable there, if it is e.g. a statement > + expression, temporaries in it might not end up being > + addressable. They might be already used in the IL and thus > + it is too late to make them addressable now though. */ > + tree x = TREE_VALUE (link); > + while (handled_component_p (x)) > + x = TREE_OPERAND (x, 0); > + if (TREE_CODE (x) == MEM_REF > + && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR) > + x = TREE_OPERAND (TREE_OPERAND (x, 0), 0); > + if ((TREE_CODE (x) == VAR_DECL > + || TREE_CODE (x) == PARM_DECL > + || TREE_CODE (x) == RESULT_DECL) > + && !TREE_ADDRESSABLE (x) > + && is_gimple_reg (x)) > + tret = GS_ERROR; > + } > mark_addressable (TREE_VALUE (link)); > if (tret == GS_ERROR) > { > --- gcc/testsuite/c-c++-common/pr67653.c.jj 2016-01-18 16:03:49.302899912 > +0100 > +++ gcc/testsuite/c-c++-common/pr67653.c 2016-01-18 16:03:20.000000000 > +0100 > @@ -0,0 +1,8 @@ > +/* PR middle-end/67653 */ > +/* { dg-do compile } */ > + > +void > +foo (void) > +{ > + __asm__ ("" : : "m" (({ static int a; a; }))); /* { dg-error "memory > input 0 is not directly addressable" } */ > +} > --- gcc/testsuite/gcc.dg/torture/pr29119.c.jj 2014-09-25 15:02:28.000000000 > +0200 > +++ gcc/testsuite/gcc.dg/torture/pr29119.c 2016-01-18 22:33:32.090515087 > +0100 > @@ -2,6 +2,6 @@ > > void ldt_add_entry(void) > { > - __asm__ ("" :: "m"(({unsigned __v; __v;}))); > + __asm__ ("" :: "m"(({unsigned __v; __v;}))); /* { dg-error "memory > input 0 is not directly addressable" } */ > } > > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)