Message ID | 20101104201237.GA29412@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On Thu, Nov 4, 2010 at 9:12 PM, Jakub Jelinek <jakub@redhat.com> wrote: > Hi! > > We currently ICE in various ways when "m" operand has pre or post > increment/decrement. We reject "m" (x + 1) and & which is roughly > what "m" does doesn't accept x++ or ++x either, so I think rejecting > it is the best thing to do. The ICEs are because the FEs > don't mark the operand addressable, so we get invalid gimple. > > In theory for POST increment/decrement we could instead just > mark their operand addressable, but for PRE increment/decrement > we still ICE with that badly. > > What do you think about this? > Bootstrapped/regtested on x86_64-linux and i686-linux as usual. I think it's a reasonable thing to do. We should have discovered all code that does this by now (I guess it just worked pre-tree-ssa?) Thanks, Richard. > 2010-11-04 Jakub Jelinek <jakub@redhat.com> > > PR middle-end/43690 > * gimplify.c (gimplify_asm_expr): If a "m" input is a > {pre,post}{in,de}crement, fail. > > * c-c++-common/pr43690.c: New test. > > --- gcc/gimplify.c.jj 2010-03-26 17:13:37.000000000 +0100 > +++ gcc/gimplify.c 2010-04-12 11:35:52.000000000 +0200 > @@ -4989,6 +4989,13 @@ gimplify_asm_expr (tree *expr_p, gimple_ > /* If the operand is a memory input, it should be an lvalue. */ > if (!allows_reg && allows_mem) > { > + tree inputv = TREE_VALUE (link); > + STRIP_NOPS (inputv); > + if (TREE_CODE (inputv) == PREDECREMENT_EXPR > + || TREE_CODE (inputv) == PREINCREMENT_EXPR > + || TREE_CODE (inputv) == POSTDECREMENT_EXPR > + || TREE_CODE (inputv) == POSTINCREMENT_EXPR) > + TREE_VALUE (link) = error_mark_node; > tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, > is_gimple_lvalue, fb_lvalue | fb_mayfail); > mark_addressable (TREE_VALUE (link)); > --- gcc/testsuite/c-c++-common/pr43690.c.jj 2010-04-12 11:14:44.000000000 +0200 > +++ gcc/testsuite/c-c++-common/pr43690.c 2010-04-12 11:37:33.000000000 +0200 > @@ -0,0 +1,13 @@ > +/* PR middle-end/43690 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > + > +void > +foo (char *x) > +{ > + asm ("" : : "m" (x++)); /* { dg-error "is not directly addressable" } */ > + asm ("" : : "m" (++x)); /* { dg-error "is not directly addressable" } */ > + asm ("" : : "m" (x--)); /* { dg-error "is not directly addressable" } */ > + asm ("" : : "m" (--x)); /* { dg-error "is not directly addressable" } */ > + asm ("" : : "m" (x + 1)); /* { dg-error "is not directly addressable" } */ > +} > > Jakub >
On Nov 5, 2010, at 6:20 AM, Richard Guenther wrote: > On Thu, Nov 4, 2010 at 9:12 PM, Jakub Jelinek <jakub@redhat.com> wrote: >> Hi! >> >> We currently ICE in various ways when "m" operand has pre or post >> increment/decrement. We reject "m" (x + 1) and & which is roughly >> what "m" does doesn't accept x++ or ++x either, so I think rejecting >> it is the best thing to do. The ICEs are because the FEs >> don't mark the operand addressable, so we get invalid gimple. >> >> In theory for POST increment/decrement we could instead just >> mark their operand addressable, but for PRE increment/decrement >> we still ICE with that badly. >> >> What do you think about this? >> Bootstrapped/regtested on x86_64-linux and i686-linux as usual. > > I think it's a reasonable thing to do. We should have discovered > all code that does this by now (I guess it just worked pre-tree-ssa?) I'm puzzled. Does this change make "m" operands reject things like x++ as "not addressable even on targets that have such addressing modes? paul
On Fri, Nov 05, 2010 at 11:20:05AM +0100, Richard Guenther wrote: > On Thu, Nov 4, 2010 at 9:12 PM, Jakub Jelinek <jakub@redhat.com> wrote: > I think it's a reasonable thing to do. We should have discovered > all code that does this by now (I guess it just worked pre-tree-ssa?) On that testcase 3.4 diagnoses: pr43690.c:8: warning: use of memory input without lvalue in asm operand 0 is deprecated pr43690.c:10: warning: use of memory input without lvalue in asm operand 0 is deprecated pr43690.c:12: warning: use of memory input without lvalue in asm operand 0 is deprecated pr43690.c:8: error: impossible constraint in `asm' pr43690.c:10: error: impossible constraint in `asm' Surprisingly it accepted preincrement/postincrement, even without warning (but that's quite hard to handle), for "m" (x + 1) it just warned and for post increment/decrement it errored out. For "m" (x + 1) we just error out starting with 4.0, after all it has been deprecated. And, ++x is not an lvalue either, so we can just say it has been deprecated too, eventhough we (incorrectly) didn't warn about it in 3.4. Jakub
On Fri, Nov 05, 2010 at 06:55:00AM -0400, Paul Koning wrote: > > On Thu, Nov 4, 2010 at 9:12 PM, Jakub Jelinek <jakub@redhat.com> wrote: > >> Hi! > >> > >> We currently ICE in various ways when "m" operand has pre or post > >> increment/decrement. We reject "m" (x + 1) and & which is roughly > >> what "m" does doesn't accept x++ or ++x either, so I think rejecting > >> it is the best thing to do. The ICEs are because the FEs > >> don't mark the operand addressable, so we get invalid gimple. > >> > >> In theory for POST increment/decrement we could instead just > >> mark their operand addressable, but for PRE increment/decrement > >> we still ICE with that badly. > >> > >> What do you think about this? > >> Bootstrapped/regtested on x86_64-linux and i686-linux as usual. > > > > I think it's a reasonable thing to do. We should have discovered > > all code that does this by now (I guess it just worked pre-tree-ssa?) > > I'm puzzled. Does this change make "m" operands reject things like x++ as > "not addressable even on targets that have such addressing modes? "m" (x++) has nothing to do with incdec addressing modes. It is not the address that is being post incremented, it is the value. "m" (*x++) is of course accepted (but won't use incdec addressing mode in current gcc either, you need for that "m<>" (*x++). Jakub
On Nov 5, 2010, at 7:02 AM, Jakub Jelinek wrote: > On Fri, Nov 05, 2010 at 06:55:00AM -0400, Paul Koning wrote: >>> On Thu, Nov 4, 2010 at 9:12 PM, Jakub Jelinek <jakub@redhat.com> wrote: >>>> Hi! >>>> >>>> We currently ICE in various ways when "m" operand has pre or post >>>> increment/decrement. We reject "m" (x + 1) and & which is roughly >>>> what "m" does doesn't accept x++ or ++x either, so I think rejecting >>>> it is the best thing to do. The ICEs are because the FEs >>>> don't mark the operand addressable, so we get invalid gimple. >>>> >>>> In theory for POST increment/decrement we could instead just >>>> mark their operand addressable, but for PRE increment/decrement >>>> we still ICE with that badly. >>>> >>>> What do you think about this? >>>> Bootstrapped/regtested on x86_64-linux and i686-linux as usual. >>> >>> I think it's a reasonable thing to do. We should have discovered >>> all code that does this by now (I guess it just worked pre-tree-ssa?) >> >> I'm puzzled. Does this change make "m" operands reject things like x++ as >> "not addressable even on targets that have such addressing modes? > > "m" (x++) has nothing to do with incdec addressing modes. It is not > the address that is being post incremented, it is the value. Thanks, I misread that. paul
--- gcc/gimplify.c.jj 2010-03-26 17:13:37.000000000 +0100 +++ gcc/gimplify.c 2010-04-12 11:35:52.000000000 +0200 @@ -4989,6 +4989,13 @@ gimplify_asm_expr (tree *expr_p, gimple_ /* If the operand is a memory input, it should be an lvalue. */ if (!allows_reg && allows_mem) { + tree inputv = TREE_VALUE (link); + STRIP_NOPS (inputv); + if (TREE_CODE (inputv) == PREDECREMENT_EXPR + || TREE_CODE (inputv) == PREINCREMENT_EXPR + || TREE_CODE (inputv) == POSTDECREMENT_EXPR + || TREE_CODE (inputv) == POSTINCREMENT_EXPR) + TREE_VALUE (link) = error_mark_node; tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, is_gimple_lvalue, fb_lvalue | fb_mayfail); mark_addressable (TREE_VALUE (link)); --- gcc/testsuite/c-c++-common/pr43690.c.jj 2010-04-12 11:14:44.000000000 +0200 +++ gcc/testsuite/c-c++-common/pr43690.c 2010-04-12 11:37:33.000000000 +0200 @@ -0,0 +1,13 @@ +/* PR middle-end/43690 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void +foo (char *x) +{ + asm ("" : : "m" (x++)); /* { dg-error "is not directly addressable" } */ + asm ("" : : "m" (++x)); /* { dg-error "is not directly addressable" } */ + asm ("" : : "m" (x--)); /* { dg-error "is not directly addressable" } */ + asm ("" : : "m" (--x)); /* { dg-error "is not directly addressable" } */ + asm ("" : : "m" (x + 1)); /* { dg-error "is not directly addressable" } */ +}