https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80053
--- Comment #4 from rguenther at suse dot de <rguenther at suse dot de> --- On Thu, 16 Mar 2017, amonakov at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80053 > > --- Comment #2 from Alexander Monakov <amonakov at gcc dot gnu.org> --- > (In reply to Richard Biener from comment #1) > > The question is whether the transform at hand is valid if the label is > > duplicated > > but all referers still refer to the original one (so if the label is dropped > > at duplication time). > > Well, you still need to initialize 'lp' somehow, so I don't follow. To the value in the other BB/function. This works if the jump targets are semantically compatible. For function cloning it's probably hard to say as things like frame allocation may be incompatible. For BB level it might be possible. > > The current handling for cloning is certainly too conservative. > > How so? I find that it's not conservative enough: it's possible to break it > even without resorting to inline asm! The following testcase is miscompiled > at > -O3, because thanks to function cloning the .constprop clone will try to jump > to the general implementation. Their epilogues are incompatible, so it > manifests with a crash. Interesting ;) And worth a separate bug. > #include <stdio.h> > __attribute__((noinline, noclone)) > static int noop(char *c) > { > return 1; > } > __attribute__((noinline)) > static int cloneme(int p, void **target) > { > if (p == -1) > *target = &&L1; > if (p == -2) > *target = &&L2; > if (p < 0) > return 0; > char *tmp = 0; > if (p) { > puts("p != 0"); > tmp = __builtin_alloca(p); > } else > puts("p == 0"); > goto **target; > L1: > return 0; > L2: > return noop(tmp); > } > > int main(int argc, char *argv[]) > { > void *target1, *target2; > cloneme(-1, &target1); > cloneme(-2, &target2); > for (int i=0; i<10; i++) > cloneme(0, &target1); > cloneme(argc, &target2); > } > >