OSDN Git Service

PR inline-asm/50571
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Sep 2011 15:01:27 +0000 (15:01 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Sep 2011 15:01:27 +0000 (15:01 +0000)
* gimple-fold.c (fold_stmt_1) <case GIMPLE_ASM>: If
input constraints allow mem and not reg, pass true instead of
false as second argument to maybe_fold_reference.

* gcc.dg/pr50571.c: New test.

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

gcc/ChangeLog
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr50571.c [new file with mode: 0644]

index 5195d04..c0159e8 100644 (file)
@@ -1,5 +1,10 @@
 2011-09-30  Jakub Jelinek  <jakub@redhat.com>
 
+       PR inline-asm/50571
+       * gimple-fold.c (fold_stmt_1) <case GIMPLE_ASM>: If
+       input constraints allow mem and not reg, pass true instead of
+       false as second argument to maybe_fold_reference.
+
        PR tree-optimization/46309
        * fold-const.c (make_range, merge_ranges): Remove prototypes.
        (make_range_step): New function.
index e345058..f8e5035 100644 (file)
@@ -1201,28 +1201,45 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace)
 
     case GIMPLE_ASM:
       /* Fold *& in asm operands.  */
-      for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
-       {
-         tree link = gimple_asm_output_op (stmt, i);
-         tree op = TREE_VALUE (link);
-         if (REFERENCE_CLASS_P (op)
-             && (op = maybe_fold_reference (op, true)) != NULL_TREE)
-           {
-             TREE_VALUE (link) = op;
-             changed = true;
-           }
-       }
-      for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
-       {
-         tree link = gimple_asm_input_op (stmt, i);
-         tree op = TREE_VALUE (link);
-         if (REFERENCE_CLASS_P (op)
-             && (op = maybe_fold_reference (op, false)) != NULL_TREE)
-           {
-             TREE_VALUE (link) = op;
-             changed = true;
-           }
-       }
+      {
+       size_t noutputs;
+       const char **oconstraints;
+       const char *constraint;
+       bool allows_mem, allows_reg;
+
+       noutputs = gimple_asm_noutputs (stmt);
+       oconstraints = XALLOCAVEC (const char *, noutputs);
+
+       for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
+         {
+           tree link = gimple_asm_output_op (stmt, i);
+           tree op = TREE_VALUE (link);
+           oconstraints[i]
+             = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+           if (REFERENCE_CLASS_P (op)
+               && (op = maybe_fold_reference (op, true)) != NULL_TREE)
+             {
+               TREE_VALUE (link) = op;
+               changed = true;
+             }
+         }
+       for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
+         {
+           tree link = gimple_asm_input_op (stmt, i);
+           tree op = TREE_VALUE (link);
+           constraint
+             = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+           parse_input_constraint (&constraint, 0, 0, noutputs, 0,
+                                   oconstraints, &allows_mem, &allows_reg);
+           if (REFERENCE_CLASS_P (op)
+               && (op = maybe_fold_reference (op, !allows_reg && allows_mem))
+                  != NULL_TREE)
+             {
+               TREE_VALUE (link) = op;
+               changed = true;
+             }
+         }
+      }
       break;
 
     case GIMPLE_DEBUG:
index 59cae6b..7005e74 100644 (file)
@@ -1,5 +1,8 @@
 2011-09-30  Jakub Jelinek  <jakub@redhat.com>
 
+       PR inline-asm/50571
+       * gcc.dg/pr50571.c: New test.
+
        PR tree-optimization/46309
        * gcc.dg/pr46309.c: New test.
 
diff --git a/gcc/testsuite/gcc.dg/pr50571.c b/gcc/testsuite/gcc.dg/pr50571.c
new file mode 100644 (file)
index 0000000..3fb4310
--- /dev/null
@@ -0,0 +1,11 @@
+/* PR inline-asm/50571 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+static const int var[4] = { 1, 2, 3, 4 };
+
+void
+foo (void)
+{
+  __asm volatile ("" : : "m" (*(int *) var));
+}