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.

Reply via email to