https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109907
--- Comment #16 from Andrew Pinski <pinskia at gcc dot gnu.org> --- (In reply to Andrew Pinski from comment #14) > Actually I take back on what is going on those 3. But I will be looking into > it. > > > x.0_1 = (signed long) x_4(D); > _2 = x.0_1 >> 31; > _3 = (unsigned char) _2; > _5 = _3 & 1; we could pattern match this on the gimple using something like: (simplify (bit_and (convert? (rshift (nop_convert? @1) INTEGER_CST@2)) integer_onep) (if (wi::to_wide (@2) == TYPE_PRECISION (TREE_TYPE (@0)) - 1) (with { tree utype = unsigned_type_for (type); } (convert (rshift (convert:utype @1) @2))) But that still fails because combine really does not like subregs: Trying 6 -> 12: 6: r47:SI=r48:SI 0>>0x1f REG_DEAD r48:SI 12: r24:QI=r47:SI#0 REG_DEAD r47:SI Failed to match this instruction: (set (reg/i:QI 24 r24) (subreg:QI (lshiftrt:SI (reg:SI 48) (const_int 31 [0x1f])) 0))