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)

Reply via email to