https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83653
--- Comment #8 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
Ah, I see what the problem is.
unsigned long i, nr = 1UL << compound_order(page);
...
page_ref_sub(page, nr); // calls __builtin_constant_p(nr) eventually
The problem is that there is a path to __builtin_constant_p(nr) for which NR is
0, and thus a constant. This is because compound_order() is defined as:
static inline unsigned int compound_order(struct page *page)
{
if (!PageHead(page))
return 0;
return page[1].compound_order;
}
The dom2 threading pass is isolating the path returning 0, and realizing that
that particular path is a constant. Your series of if's does not handle 0, and
you get the __bad_increment_for_ia64_fetch_and_add exposed.
Don't blame me, I'm just the messenger :).
Perhaps Richi has a suggestion on how to code your macro.
If, as Richard says, this is a known quirk, perhaps we should document it in
the section for __builtin_constant_p() in the manual, along with a suggestion
on how to code an alternative.