https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63259
--- Comment #18 from Oleg Endo <olegendo at gcc dot gnu.org> --- (In reply to Oleg Endo from comment #17) > (In reply to thopre01 from comment #16) > > > > Did we? All I can find is you and Andreas mentionning that it should work > > because it will be sign extended to int when doing the bitwise AND with > > 0xFF00. > > > > What did I miss? > > Ah sorry ... me bad. I haven't tried increasing the 'level' with the > bswaphi expander pattern in place. Will do that later. So I did. Increasing the limit to limit += 2 + (int) ceil_log2 ... works for me for the signed short case. However, the following function from the CSiBE set: void _nrrdSwap32Endian(void *_data, size_t N) { int *data, w, fix; size_t I; if (_data) { data = (int *)_data; for (I=0; I<N; I++) { w = data[I]; fix = (w & 0x000000FF); fix = ((w & 0x0000FF00) >> 0x08) | (fix << 0x08); fix = ((w & 0x00FF0000) >> 0x10) | (fix << 0x08); fix = ((w & 0xFF000000) >> 0x18) | (fix << 0x08); data[I] = fix; } } } seems to require 'limit += 3 + (int) ...' for the bswap insn to be detected. Then, this fine function (from the same set) void _nrrdSwap64Endian(void *_data, size_t N) { airLLong *data, l, fix; size_t I; if (_data) { data = (airLLong *)_data; for (I=0; I<N; I++) { l = data[I]; fix = (l & 0x00000000000000FF); fix = ((l & 0x000000000000FF00) >> 0x08) | (fix << 0x08); fix = ((l & 0x0000000000FF0000) >> 0x10) | (fix << 0x08); fix = ((l & 0x00000000FF000000) >> 0x18) | (fix << 0x08); #if defined(_WIN32) fix = ((l & 0x000000FF00000000i64) >> 0x20) | (fix << 0x08); fix = ((l & 0x0000FF0000000000i64) >> 0x28) | (fix << 0x08); fix = ((l & 0x00FF000000000000i64) >> 0x30) | (fix << 0x08); fix = ((l & 0xFF00000000000000i64) >> 0x38) | (fix << 0x08); #else fix = ((l & 0x000000FF00000000LL) >> 0x20) | (fix << 0x08); fix = ((l & 0x0000FF0000000000LL) >> 0x28) | (fix << 0x08); fix = ((l & 0x00FF000000000000LL) >> 0x30) | (fix << 0x08); fix = ((l & 0xFF00000000000000LL) >> 0x38) | (fix << 0x08); #endif data[I] = fix; } } } requires 'limit += 6 + (int) ...' (luckily, there's no _nrrdSwap128Endian in the set)