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? 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; +} -- 2.35.3