#include <algorithm> #include <iterator> template < typename T > void reverse( T& t ) { unsigned char* bytes = reinterpret_cast< unsigned char* >( &t ); std::swap_ranges( bytes, bytes + sizeof( T ) / 2, std::reverse_iterator< unsigned char* >( bytes + sizeof( T ) ) ); } template void reverse( std::size_t& );
attached testcase produces massive byte-moves instead of bswap. $ g++ -Wall swap_ranges.cpp -fomit-frame-pointer -m32 -O3 -c 00000000 <void reverse<unsigned int>(unsigned int&)>: 0: 8b 44 24 04 mov 0x4(%esp),%eax 4: 0f b6 08 movzbl (%eax),%ecx 7: 0f b6 50 03 movzbl 0x3(%eax),%edx b: 88 48 03 mov %cl,0x3(%eax) e: 0f b6 48 01 movzbl 0x1(%eax),%ecx 12: 88 10 mov %dl,(%eax) 14: 0f b6 50 02 movzbl 0x2(%eax),%edx 18: 88 48 02 mov %cl,0x2(%eax) 1b: 88 50 01 mov %dl,0x1(%eax) 1e: c3 ret 0000000000000000 <void reverse<unsigned long>(unsigned long&)>: 0: 0f b6 17 movzbl (%rdi),%edx 3: 0f b6 47 07 movzbl 0x7(%rdi),%eax 7: 88 57 07 mov %dl,0x7(%rdi) a: 88 07 mov %al,(%rdi) c: 0f b6 57 01 movzbl 0x1(%rdi),%edx 10: 0f b6 47 06 movzbl 0x6(%rdi),%eax 14: 88 57 06 mov %dl,0x6(%rdi) 17: 88 47 01 mov %al,0x1(%rdi) 1a: 0f b6 57 02 movzbl 0x2(%rdi),%edx 1e: 0f b6 47 05 movzbl 0x5(%rdi),%eax 22: 88 57 05 mov %dl,0x5(%rdi) 25: 88 47 02 mov %al,0x2(%rdi) 28: 0f b6 57 03 movzbl 0x3(%rdi),%edx 2c: 0f b6 47 04 movzbl 0x4(%rdi),%eax 30: 88 57 04 mov %dl,0x4(%rdi) 33: 88 47 03 mov %al,0x3(%rdi) 36: c3 retq -- Summary: massive moves instead of bswap{l,q} Product: gcc Version: 4.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: pluto at agmk dot net GCC target triplet: x86_64-*-*, i?86-*-* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32605