diff mbox series

middle-end/115426 - wrong gimplification of "rm" asm output operand

Message ID 20240611112116.A81F9385DC20@sourceware.org
State New
Headers show
Series middle-end/115426 - wrong gimplification of "rm" asm output operand | expand

Commit Message

Richard Biener June 11, 2024, 11:20 a.m. UTC
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 mbox series

Patch

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