https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91204
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- --- gcc/optabs.c.jj 2019-07-15 10:53:10.743205405 +0200 +++ gcc/optabs.c 2019-07-19 00:38:20.271852242 +0200 @@ -2972,6 +2972,17 @@ expand_unop (machine_mode mode, optab un return target; } + /* Emit ~op0 as op0 ^ -1. */ + if (unoptab == one_cmpl_optab + && (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT) + && optab_handler (xor_optab, mode) != CODE_FOR_nothing) + { + temp = expand_binop (mode, xor_optab, op0, CONSTM1_RTX (mode), + target, unsignedp, OPTAB_DIRECT); + if (temp) + return temp; + } + if (optab_to_code (unoptab) == NEG) { /* Try negating floating point values by flipping the sign bit. */ seems to work for me. Or of course something similar can be done in config/i386/mmx.md, basically copy the sse.md one_cmpl<mode>2 pattern to mmx.md with TARGET_MMX_WITH_SSE and MMXMODEI iterator.