https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115102
--- Comment #4 from Uroš Bizjak <ubizjak at gmail dot com> --- (In reply to Richard Biener from comment #1) > though on x86 there's no high word preserving swap of the lower 2 bytes. There is, please try: asm ("xchgb %h0, %b0" : "+Q" (val)); like: --cut here-- #include <stdint.h> #include <stdio.h> uint32_t __attribute__((noinline)) bswap8(uint32_t val) { return (val & 0xffff0000) | ((val & 0xff00) >> 8) | ((val & 0xff) << 8); } uint32_t __attribute__((noinline)) bswap8_new(uint32_t val) { asm ("xchgb %h0, %b0" : "+Q" (val)); return val; } int main () { uint32_t a = 0x10325476; printf ("%x %x\n", bswap8 (a), bswap8_new (a)); return 0; } --cut here-- we already have: (define_insn "bswaphi_lowpart" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r")) (bswap:HI (match_dup 0))) (clobber (reg:CC FLAGS_REG))] "" "@ xchg{b}\t{%h0, %b0|%b0, %h0} rol{w}\t{$8, %0|%0, 8}" but bswaphi2 named pattern is enabled only for TARGET_MOVBE. Time to fix this ;)