https://gcc.gnu.org/g:a4bbdec2be1c9f8fb49276b8a54ee86024ceac17

commit r15-1837-ga4bbdec2be1c9f8fb49276b8a54ee86024ceac17
Author: Richard Biener <rguent...@suse.de>
Date:   Tue Jun 11 13:11:08 2024 +0200

    middle-end/115426 - wrong gimplification of "rm" asm output operand
    
    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.
    
            PR middle-end/115426
            * gimplify.cc (gimplify_asm_expr): Handle "rm" output
            constraint gimplified to a register (operation).
    
            * gcc.dg/pr115426.c: New testcase.

Diff:
---
 gcc/gimplify.cc                 |  8 ++++++++
 gcc/testsuite/gcc.dg/pr115426.c | 14 ++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 622c51d5c3f..5a9627c4acf 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -7040,6 +7040,14 @@ 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_reg
+         && allows_mem
+         && (is_gimple_reg (TREE_VALUE (link))
+             || (handled_component_p (TREE_VALUE (link))
+                 && is_gimple_reg (TREE_OPERAND (TREE_VALUE (link), 0)))))
+       allows_mem = 0;
+
       /* 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..02bfc3f21fa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr115426.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu11" } */
+
+_Complex int fcs (_Complex int r)
+{
+  __asm__("" : "=rm" (__imag__ r));
+  return r;
+}
+
+_Complex int fcs2 (_Complex int r)
+{
+  __asm__("" : "=m" (__imag__ r));
+  return r;
+}

Reply via email to