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

--- Comment #5 from Matthew Wilcox <matthew at wil dot cx> ---
Hi Aldy!

Thanks for looking into this.  Yes, I agree, there's no way that GCC can know
this is a constant, but that *should* have been taken care of.  Please pardon
me copying and pasting from the original source file rather than the
preprocessed source, but I find it utterly impossible to work with the
preprocessed source ...

#define atomic_sub_return(i,v)                                          \
({                                                                      \
        int __ia64_asr_i = (i);                                         \
        (__builtin_constant_p(i)                                        \
         && (   (__ia64_asr_i ==   1) || (__ia64_asr_i ==   4)          \
             || (__ia64_asr_i ==   8) || (__ia64_asr_i ==  16)          \
             || (__ia64_asr_i ==  -1) || (__ia64_asr_i ==  -4)          \
             || (__ia64_asr_i ==  -8) || (__ia64_asr_i == -16)))        \
                ? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter)      \
                : ia64_atomic_sub(__ia64_asr_i, v);                     \
})

That __builtin_constant_p() *should* have led GCC to throw up its hands, not
bother checking for the +/- 1, 4, 8, 16 cases and just call ia64_atomic_sub(). 
Looking at the disassembly, I see a BBB bundle, indicating quite strongly to me
that it is testing for all of these cases, and the __builtin_constant_p is
being ... ignored?  misunderstood?

Thanks!

Reply via email to