https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98348
--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Created attachment 49806 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49806&action=edit gcc11-pr98348.patch So, if we go for GCC11 the way of pre-reload define_insn_and_split, this is some incremental untested progress on your patch (just the sse.md part of it). Changes: 1) it is undesirable to put SUBREGs on the SET_DEST side, as it prevents other optimizations later on 2) I don't see the point on the TARGET_AVX512BW ||, the insn in the end is plain AVX or AVX2 or SSE4* etc. one 3) handles also the const0 vector_all_ones order 4) for commutative cases allows any operand order, for others ensures the right one of the operands is register 5) handles also the LE case by swapping the comparison operands The patch doesn't handle the cases where based on the comparison one sets up floating vectors, as can be seen e.g. in: typedef float V128 __attribute__ ((vector_size(16))); typedef float V256 __attribute__ ((vector_size(32))); typedef float V512 __attribute__ ((vector_size(64))); V128 foo (V128 x) { const union U { unsigned u; float f; } u = { -1U }; return x > 0.0f ? u.f : 0.0f; } V256 bar (V256 x) { const union U { unsigned u; float f; } u = { -1U }; return x > 0.0f ? u.f : 0.0f; }