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?