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.