http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58805
--- Comment #15 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to vries from comment #14) > > No it shouldn't. It should return true if the stmt has side-effects that > > are _not_ explicit in the statement. This side-effect is explicitely there. > > Hmm, a rather deceptive name then, if gimple_stmt_has_side_effects does not > in fact tell whether a gimple statement has side-effects or not. > I wonder if any other use sites are mistaken in the semantics, and what > could be a better name. A side-effect is by definition an effect that happens "on the side", so I think the name quite matches. > A better name according to your description could be > gimple_stmt_has_implicit_side_effects, but I'm not sure I understand how to > differentiate between implicit and explicit here. Marking an asm with > volatile, is that implicit or explicit, and why? Well, is in a = b + c the computation of a + c a side-effect or not? Is in a = b the assignment to 'a' a side-effect or not. Neither I would argue. > AFAIU, the name gimple_stmt_has_call_or_volatile_side_effects reflects what > the implementation does. No, for calls the side-effects of the callee body are not explicit (unless it is pure or const). > Anyways, this tentative patch fixes the problem in tail-merge: > ... > Author: Tom de Vries <t...@codesourcery.com> > Date: Mon Oct 21 13:40:28 2013 +0200 > > * tree-ssa-tail-merge.c (stmt_local_def): Improve side-effect check. > > diff --git a/gcc/testsuite/gcc.dg/pr58805.c b/gcc/testsuite/gcc.dg/pr58805.c > new file mode 100644 > index 0000000..6e6eba5 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr58805.c > @@ -0,0 +1,23 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre" } */ > + > +static inline void bar(unsigned long *r) > +{ > + unsigned long t; > + __asm__ ( > + "movq $42, %[t]\n\t" > + "movq %[t], %[r]\n\t" > + : [t] "=&r" (t), [r] "=r" (*r) > + ); > +} > + > +void foo(int n, unsigned long *x, unsigned long *y) > +{ > + if (n == 0) > + bar(x); > + else > + bar(y); > +} > + > +/* { dg-final { scan-tree-dump-times "__asm__" 2 "pre"} } */ > +/* { dg-final { cleanup-tree-dump "pre" } } */ > diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c > index 9094935..0090da6 100644 > --- a/gcc/tree-ssa-tail-merge.c > +++ b/gcc/tree-ssa-tail-merge.c > @@ -300,7 +300,8 @@ stmt_local_def (gimple stmt) > tree val; > def_operand_p def_p; > > - if (gimple_has_side_effects (stmt)) > + if (gimple_has_side_effects (stmt) > + || gimple_vdef (stmt) != NULL_TREE) > return false; > > def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF); > ... > > I'll test this one. Looks good to me. Btw, you'd have had the same issue with the aggregate return of a pure/const function call, no?