https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83565
--- Comment #1 from Sergei Trofimovich <slyfox at inbox dot ru> --- Here is disassembled dump of gcc -O1 result (it's slightly easier to reason about than gcc's assembly output): Dump of assembler code for function bug: 0x40000000000005f0 <+0>: [MII] mov r14=r12 // store 'ss=0xffffffff' on stack 0x40000000000005f1 <+1>: mov r15=-1;; 0x40000000000005f2 <+2>: nop.i 0x0 // store 'd=0xeeeeeeee' on stack 0x4000000000000600 <+16>: [MLX] st4.rel [r14]=r15,4 0x4000000000000601 <+17>: movl r15=0xffffffffeeeeeeee;; // reload 'd' 0x4000000000000610 <+32>: [MMI] st4.rel [r14]=r15 0x4000000000000611 <+33>: ld4.acq r15=[r14] 0x4000000000000612 <+34>: nop.i 0x0 // u32 tt = d & 0x00800000; 0x4000000000000620 <+48>: [MLX] nop.m 0x0 0x4000000000000621 <+49>: movl r14=0x800000;; 0x4000000000000630 <+64>: [MMI] and r15=r14,r15;; // u32 r = tt << 8; 0x4000000000000631 <+65>: nop.m 0x0 0x4000000000000632 <+66>: dep.z r14=r15,8,24 0x4000000000000640 <+80>: [MMI] ld4.acq r8=[r12] // *result = tt; 0x4000000000000641 <+81>: st4 [r32]=r15 0x4000000000000642 <+82>: nop.i 0x0;; // rotate //r = (r >> 31) // | (r << 1); 0x4000000000000650 <+96>: [MII] nop.m 0x0 0x4000000000000651 <+97>: mix4.r r14=r14,r14;; 0x4000000000000652 <+98>: shr.u r14=r14,31;; // u32 u = r^ss; 0x4000000000000660 <+112>: [MMI] xor r8=r8,r14;; 0x4000000000000661 <+113>: nop.m 0x0 // u32 off = u >> 1; // Note how we use 32 bits after 1-bit shift. 0x4000000000000662 <+114>: extr.u r8=r8,1,32 0x4000000000000670 <+128>: [MIB] nop.m 0x0 0x4000000000000671 <+129>: nop.i 0x0 0x4000000000000672 <+130>: br.ret.sptk.many b0;; Here 'extr.u r8=r8,1,32' should be 'extr.u r8=r8,1,31' to yield correct result. But something in RTK combine pass decided to expand 31 to 32.