2016-03-24 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 24 Mar 2016 12:19:56 +0000 (12:19 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 24 Mar 2016 12:19:56 +0000 (12:19 +0000)
PR middle-end/70370
* gimplify.c (gimplify_asm_expr): Handle !allows_mem outputs
with register bases.

* gcc.dg/torture/pr70370.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234453 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr70370.c [new file with mode: 0644]

index 3c80e77..a4ade25 100644 (file)
@@ -1,5 +1,11 @@
 2016-03-24  Richard Biener  <rguenther@suse.de>
 
+       PR middle-end/70370
+       * gimplify.c (gimplify_asm_expr): Handle !allows_mem outputs
+       with register bases.
+
+2016-03-24  Richard Biener  <rguenther@suse.de>
+
        PR tree-optimization/70372
        * tree-ssa-reassoc.c (eliminate_plus_minus_pair): Use
        build_all_ones_cst to also handle vector types correctly.
index 5d03435..b9757db 100644 (file)
@@ -5191,6 +5191,32 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
          ret = tret;
        }
 
+      /* 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.  */
+      if (!allows_mem)
+       {
+         tree op = TREE_VALUE (link);
+         if (! is_gimple_val (op)
+             && is_gimple_reg_type (TREE_TYPE (op))
+             && is_gimple_reg (get_base_address (op)))
+           {
+             tree tem = create_tmp_reg (TREE_TYPE (op));
+             tree ass;
+             if (is_inout)
+               {
+                 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
+                               tem, unshare_expr (op));
+                 gimplify_and_add (ass, pre_p);
+               }
+             ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
+             gimplify_and_add (ass, post_p);
+
+             TREE_VALUE (link) = tem;
+             tret = GS_OK;
+           }
+       }
+
       vec_safe_push (outputs, link);
       TREE_CHAIN (link) = NULL_TREE;
 
index be2e416..73cb726 100644 (file)
@@ -1,3 +1,8 @@
+2016-03-24  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/70370
+       * gcc.dg/torture/pr70370.c: New testcase.
+
 2016-03-24  Tom de Vries  <tom@codesourcery.com>
 
        * gfortran.dg/goacc/data-tree.f95: Add missing initialization.
diff --git a/gcc/testsuite/gcc.dg/torture/pr70370.c b/gcc/testsuite/gcc.dg/torture/pr70370.c
new file mode 100644 (file)
index 0000000..d077bee
--- /dev/null
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+
+_Complex float
+test1 (_Complex float f)
+{
+  __asm__ ("" : "+r" (__real f));
+  return f;
+}
+
+_Complex float
+test2 (_Complex float f)
+{
+  __asm__ ("" : "=r" (__real f));
+  return f;
+}
+
+struct X { int i; };
+
+struct X 
+test3 (struct X x)
+{
+  __asm__ ("" : "=r" (x.i));
+  return x;
+}
+
+struct X
+test4 (struct X x)
+{
+  __asm__ ("" : "+r" (x.i));
+  return x;
+}
+
+struct X 
+test5 (struct X x)
+{
+  __asm__ ("" : "=r" (x));
+  return x;
+}
+
+struct X
+test6 (struct X x)
+{
+  __asm__ ("" : "+r" (x));
+  return x;
+}