https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101806
--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> --- It happens to work on x86-64(with -march=skylake-avx512) becausewe get a zero_extend instead of an and there. I still don't understand how x86 is able to figure out the &1 part. Trying 11, 9 -> 12: 11: r94:SI=zero_extend(r97:SI#0) REG_DEAD r97:SI 9: r92:SI=zero_extend(r96:SI#0) REG_DEAD r96:SI 12: {r95:SI=~r92:SI&r94:SI;clobber flags:CC;} REG_DEAD r92:SI REG_UNUSED flags:CC REG_DEAD r94:SI Failed to match this instruction: (parallel [ (set (reg:SI 95) (zero_extend:SI (and:QI (not:QI (subreg:QI (reg:SI 96) 0)) (subreg:QI (reg:SI 97) 0)))) (clobber (reg:CC 17 flags)) ]) Failed to match this instruction: (set (reg:SI 95) (zero_extend:SI (and:QI (not:QI (subreg:QI (reg:SI 96) 0)) (subreg:QI (reg:SI 97) 0)))) Successfully matched this instruction: (set (reg:QI 94 [ b ]) (and:QI (not:QI (subreg:QI (reg:SI 96) 0)) (subreg:QI (reg:SI 97) 0))) Successfully matched this instruction: (set (reg:SI 95) (zero_extend:SI (reg:QI 94 [ b ])))