aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-09-30 17:01:27 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-09-30 17:01:27 +0200
commit383841506e318ffddda4f29d7e6d8bd9933b7d45 (patch)
tree0dc48dd18357dd5c7e31ead2094f2684dcdd9cf0 /gcc
parent0ccb5dbf93d900812222d4383760d6c632bf2382 (diff)
downloadgcc-383841506e318ffddda4f29d7e6d8bd9933b7d45.zip
gcc-383841506e318ffddda4f29d7e6d8bd9933b7d45.tar.gz
gcc-383841506e318ffddda4f29d7e6d8bd9933b7d45.tar.bz2
re PR inline-asm/50571 (Undesirable folding in "m" constrained asm operands)
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. * gcc.dg/pr50571.c: New test. From-SVN: r179389
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/gimple-fold.c61
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/pr50571.c11
4 files changed, 58 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5195d04..c0159e8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index e345058..f8e5035 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 59cae6b..7005e74 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..3fb4310
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr50571.c
@@ -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));
+}