https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91204
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #3) > --- 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. Doing it in the middle-end is better IMHO. But yeah, we're somewhat sloppy with vector optabs checks in match.pd where it seems "obvious" targets need to have support...