https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89752
--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Actually can't bisect, as gcc 8 I have installed is no longer able to build r215000 or revisions around it (some error on wide-int.h: ../../gcc/wide-int.h:372:10: error: too many template-parameter-lists struct binary_traits <T1, T2, FLEXIBLE_PRECISION, FLEXIBLE_PRECISION> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ etc.). That said, if we want to fix the: struct A { A (); ~A (); short c; }; void foo () { A a0, a1; __asm volatile ("" : "+rm" (a0), "+rm" (a1)); } in the provided testcase, we could use: --- gcc/gimplify.c.jj 2019-03-07 20:45:39.168938360 +0100 +++ gcc/gimplify.c 2019-03-18 16:18:16.515466234 +0100 @@ -6155,6 +6155,19 @@ gimplify_asm_expr (tree *expr_p, gimple_ is_inout = false; } + /* If we can't make copies, we can only accept memory. */ + if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link)))) + { + if (allows_mem) + allows_reg = 0; + else + { + error ("impossible constraint in %<asm%>"); + error ("non-memory output %d must stay in memory", i); + return GS_ERROR; + } + } + if (!allows_reg && allows_mem) mark_addressable (TREE_VALUE (link)); which is something we already do for the input args, just for some strange reason not for output args as well (if we wanted to backport it, I'd leave the error part out). That said, because users can write even that: struct A { A (); ~A (); short c; }; void foo () { A a0, a1; __asm volatile ("" : "=rm" (a0), "=rm" (a1) : "0" (a0), "1" (a1)); } we need something in LRA too, that will simply treat BLKmode matching constraints when both registers and memory are allowed as if only memory was allowed.