Hi! On Fri, Sep 30, 2011 at 10:34:28AM +0200, Richard Guenther wrote: > Hmm, I don't think this change is ok. We rely on maybe_fold_reference > to re-fold mem-refs to valid gimple form (from propagating say > &a.b.c to MEM[p, 4] which first gives the invalid MEM[&a.b.c, 4] and > then the folding changes this to MEM[&a, 12]). You need to preserve that > and only disable constant folding. > > Thus I suggest to add a parameter to maybe_fold_reference that says > whether to try constant folding (we already have is_lhs, so why not > use that?)
So like this instead? 2011-09-30 Jakub Jelinek <ja...@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. * gcc.dg/pr50571.c: New test. --- gcc/gimple-fold.c.jj 2011-09-29 14:25:46.000000000 +0200 +++ gcc/gimple-fold.c 2011-09-30 10:54:10.000000000 +0200 @@ -1201,28 +1201,45 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, 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: --- gcc/testsuite/gcc.dg/pr50571.c.jj 2011-09-29 21:28:05.000000000 +0200 +++ gcc/testsuite/gcc.dg/pr50571.c 2011-09-29 21:30:08.000000000 +0200 @@ -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)); +} Jakub