https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70370

--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
Testcase for inout that now will error with the patch (but also ICEd before).

_Complex float foo (_Complex float f)
{
  __asm__ ("" : "+r" (__real f));
  return f;
}

> ./cc1 -quiet t.c -fdump-tree-all
t.c: In function ‘foo’:
t.c:3:3: error: invalid lvalue in asm output 0
   __asm__ ("" : "+r" (__real f));
   ^~~~~~~

The !allows-mem case needs to verify we have a proper gimple register type
as well of course.  The following seems to work

Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c      (revision 234415)
+++ gcc/gimplify.c      (working copy)
@@ -5191,6 +5205,33 @@ gimplify_asm_expr (tree *expr_p, gimple_
          ret = tret;
        }

+      if (!allows_mem)
+       {
+         if (! is_gimple_reg_type (TREE_TYPE (TREE_VALUE (link))))
+           {
+             error ("invalid lvalue in asm output %d", i);
+             ret = GS_ERROR;
+           }
+         else
+           {
+             tree tem = create_tmp_reg (TREE_TYPE (TREE_VALUE (link)));
+             tree ass;
+             if (is_inout)
+               {
+                 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
+                               tem, unshare_expr (TREE_VALUE (link)));
+                 gimplify_and_add (ass, pre_p);
+               }
+             ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
+                           TREE_VALUE (link), tem);
+             gimplify_and_add (ass, post_p);
+
+             TREE_VALUE (link) = tem;
+             /* create and gimplify TREE_VALUE (link) = reg on post_p.  */
+             tret = GS_OK;
+           }
+       }
+
       vec_safe_push (outputs, link);
       TREE_CHAIN (link) = NULL_TREE;

Reply via email to