On Tue, 11 Jun 2024, Richard Biener wrote:

> When the operand is gimplified to an extract of a register or a
> register we have to disallow memory as we otherwise fail to
> gimplify it properly.  Instead of
> 
>   __asm__("" : "=rm" __imag <r>);
> 
> we want
> 
>   __asm__("" : "=rm" D.2772);
>   _1 = REALPART_EXPR <r>;
>   r = COMPLEX_EXPR <_1, D.2772>;
> 
> otherwise SSA rewrite will fail and generate wrong code with 'r'
> left bare in the asm output.
> 
> Bootstrap and regtest in progress on x86_64-unknown-linux-gnu.
> 
> I've made the testcase hopefully generic enough (the bug used =X
> which I'm not sure is portable - I've used _Complex int so 'r'
> has a chance to work).
> 
> OK?

Ping.

> Thanks,
> Richard.
> 
>       PR middle-end/115426
>       * gimplify.cc (gimplify_asm_expr): Handle "rm" output
>       constraint gimplified to a register (operation).
> 
>       * gcc.dg/pr115426.c: New testcase.
> ---
>  gcc/gimplify.cc                 | 16 ++++++++++++++++
>  gcc/testsuite/gcc.dg/pr115426.c |  9 +++++++++
>  2 files changed, 25 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/pr115426.c
> 
> diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
> index 04875e8df29..450be45422f 100644
> --- a/gcc/gimplify.cc
> +++ b/gcc/gimplify.cc
> @@ -7044,6 +7044,22 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, 
> gimple_seq *post_p)
>         ret = tret;
>       }
>  
> +      /* If the gimplified operand is a register we do not allow memory.  */
> +      if (allows_mem
> +       && (is_gimple_reg (TREE_VALUE (link))
> +           || (handled_component_p (TREE_VALUE (link))
> +               && is_gimple_reg (TREE_OPERAND (TREE_VALUE (link), 0)))))
> +     {
> +       if (allows_reg)
> +         allows_mem = 0;
> +       else
> +         {
> +           error ("impossible constraint in %<asm%>");
> +           error ("non-memory output %d must stay in memory", i);
> +           return GS_ERROR;
> +         }
> +     }
> +
>        /* If the constraint does not allow memory make sure we gimplify
>           it to a register if it is not already but its base is.  This
>        happens for complex and vector components.  */
> diff --git a/gcc/testsuite/gcc.dg/pr115426.c b/gcc/testsuite/gcc.dg/pr115426.c
> new file mode 100644
> index 00000000000..8432f102992
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr115426.c
> @@ -0,0 +1,9 @@
> +/* { dg-do compile } */
> +/* { dg-options "-std=gnu11" } */
> +
> +_Complex int fcs()
> +{
> +  _Complex int r;
> +  __asm__("" : "=rm" (__imag__ r));
> +  return r;
> +}
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to