https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121298
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed| |2025-07-29 Ever confirmed|0 |1 Status|UNCONFIRMED |NEW --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- find_bswap_or_nop_1 finds _1 = val_7(D) & 4294901760; and $19 = {n = 0x4030102, type = <integer_type 0x7ffff6822690 unsigned int>, base_addr = <tree 0x0>, offset = <tree 0x0>, bytepos = {coeffs = {0}}, src = <ssa_name 0x7ffff680d948 7>, alias_set = <tree 0x0>, vuse = <tree 0x0>, range = 4, n_ops = 3} which I think "just" lacks some extra processing to figure the HImode rotate and the IOR with the remaining bits in the base. But the code is already a bit messy. It's the bswap pass performing the transform in both cases at the moment. bswapdst_4 = __builtin_bswap32 (val_7(D)); bswapmaskdst_11 = bswapdst_4 & 4294901760; _10 = bswapmaskdst_11 r<< 16; _8 = _1 | _10; Both testcases are actually the same btw, just associating bit-and and shift. unsigned int bswap8 (unsigned int val) { return (val & 0xffff0000) | ((val & 0xff00) >> 8) | ((val & 0xff) << 8); } void ext(int x); void foo(int x) { ext((x&~0xffff)|((x>>8)&0xff)|((x&0xff)<<8)); } without the causing rev. we get the same result for the outer operation but then the tail has the HImode rotate associated together. But this is visible in the whole operation as well.