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!