https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80053

            Bug ID: 80053
           Summary: Label with address taken should prevent duplication of
                    containing basic block
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: amonakov at gcc dot gnu.org
  Target Milestone: ---

Today, GCC considers all BBs clonable on GIMPLE, as indicated by
tree-cfg.c:gimple_can_duplicate_bb_p, but, at the same time, not all functions
are clonable: those functions that have labels with address taken and stored
into a static variable are considered non-clonable.  This seems inconsistent. 
Taking address of a label should generally prevent cloning of its BB.

Here's a testcase that is actually miscompiled at -O3, because after loop
unswitching one of the cloned loops will jump to a label in another clone:

#include <stdio.h>
static __attribute__((noinline,noclone))
void h(int n, int p)
{
  void *lp = &&l;
  asm("" : "+r"(lp));
  for (; n; n--) {
    if (p)
      puts("p != 0");
    else
      puts("p == 0");
    asm goto("jmp *%0" : : "r"(lp) : : l);
l:;
  }
}
int main()
{
  h(2, 0);
  h(2, 1);
}

My understanding that this is an omission, and both
{gimple,cfgrtl}_can_duplicate_bb_p should return false when the BB has its
address taken.  Unless I'm missing something and this is not an oversight?

Reply via email to